kramdown-plantuml 1.1.13 → 1.3.2
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/.github/workflows/ruby.yml +3 -3
- data/README.md +33 -2
- data/bin/net/sourceforge/plantuml/plantuml/{1.2021.12/plantuml-1.2021.12.jar → 1.2021.16/plantuml-1.2021.16.jar} +0 -0
- data/kramdown-plantuml.gemspec +1 -0
- data/lib/kramdown-plantuml/executor.rb +1 -1
- data/lib/kramdown-plantuml/jekyll_provider.rb +6 -42
- data/lib/kramdown-plantuml/none_s.rb +17 -0
- data/lib/kramdown-plantuml/options.rb +21 -1
- data/lib/kramdown-plantuml/{diagram.rb → plantuml_diagram.rb} +12 -23
- data/lib/kramdown-plantuml/plantuml_error.rb +5 -5
- data/lib/kramdown-plantuml/plantuml_result.rb +9 -26
- data/lib/kramdown-plantuml/style_builder.rb +56 -0
- data/lib/kramdown-plantuml/svg_diagram.rb +115 -0
- data/lib/kramdown-plantuml/theme.rb +22 -15
- data/lib/kramdown-plantuml/version.rb +1 -1
- data/lib/kramdown-plantuml.rb +0 -3
- data/lib/kramdown_html.rb +9 -19
- data/pom.xml +1 -1
- metadata +21 -5
- data/lib/kramdown-plantuml/jekyll_page_processor.rb +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 716bd98dfc84efc97e64f12e8c1f68c1ee7a982e1d1ea33eabdf0f74b4560c04
|
4
|
+
data.tar.gz: 56254a3d065d7c69f2744cca59d32974e37f3e773bceccc2c63ab8dc151a5ace
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e19ff0d0e8b1b90f5a5e19595c95982c9e6c126b1b54b5238c0ee1ac81463aaf63350be0ea90c04844cbc7fca5c126cadd86fec50073ed9af0bf83b9800a706
|
7
|
+
data.tar.gz: c0dea81be5cd8bbf9c9541b4941cfd4c0ab05700a092a6b4672ec7adfe96f5e2212c22861dfcd0e86d1e90611b8bf2734da12d12b05853239ffa582b3b67bcc5
|
data/.github/workflows/ruby.yml
CHANGED
@@ -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.
|
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.
|
24
|
+
uses: gittools/actions/gitversion/execute@v0.9.11
|
25
25
|
|
26
26
|
- name: Create variables
|
27
27
|
id: variables
|
@@ -43,7 +43,7 @@ jobs:
|
|
43
43
|
java-version: 14
|
44
44
|
|
45
45
|
- name: Cache Maven dependencies
|
46
|
-
uses: actions/cache@v2.1.
|
46
|
+
uses: actions/cache@v2.1.7
|
47
47
|
with:
|
48
48
|
path: ~/.m2/repository
|
49
49
|
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
data/README.md
CHANGED
@@ -127,7 +127,38 @@ kramdown:
|
|
127
127
|
plantuml:
|
128
128
|
theme:
|
129
129
|
name: my-custom-theme
|
130
|
-
directory:
|
130
|
+
directory: spec/examples
|
131
|
+
```
|
132
|
+
|
133
|
+
### Dimensions and Styling
|
134
|
+
|
135
|
+
It's possible to customize the dimensions and scale of the diagram by providing
|
136
|
+
the `width`, `height` and `scale` configuration keys. It's also possible to add
|
137
|
+
arbitrary styling with the `style` key.
|
138
|
+
|
139
|
+
`scale` is applied before the diagram is generated, while `width` and `height`
|
140
|
+
are applied after, meaning they can be combined (to most likely detrimental
|
141
|
+
results, but YOLO).
|
142
|
+
|
143
|
+
```yaml
|
144
|
+
kramdown:
|
145
|
+
plantuml:
|
146
|
+
width: 200px
|
147
|
+
height: 100px
|
148
|
+
scale: 2
|
149
|
+
style: "border: 1px solid black"
|
150
|
+
```
|
151
|
+
|
152
|
+
To remove the `width`, `height` and `style` attributes from the `<svg />`
|
153
|
+
element, set the key's value to `none`. `scale` does not support a value of
|
154
|
+
`none` as it does not need to be removed.
|
155
|
+
|
156
|
+
```yaml
|
157
|
+
kramdown:
|
158
|
+
plantuml:
|
159
|
+
width: none
|
160
|
+
height: none
|
161
|
+
style: none
|
131
162
|
```
|
132
163
|
|
133
164
|
### Errors
|
@@ -199,7 +230,7 @@ agreement][cla].
|
|
199
230
|
[codacy]: https://www.codacy.com/gh/SwedbankPay/kramdown-plantuml/dashboard?utm_source=github.com&utm_medium=referral&utm_content=SwedbankPay/kramdown-plantuml&utm_campaign=Badge_Grade
|
200
231
|
[codecov-badge]: https://codecov.io/gh/SwedbankPay/kramdown-plantuml/branch/main/graph/badge.svg?token=U3QJLVG3HY
|
201
232
|
[codecov]: https://codecov.io/gh/SwedbankPay/kramdown-plantuml/
|
202
|
-
[diagram-svg]: ./spec/examples/diagram.svg
|
233
|
+
[diagram-svg]: ./spec/examples/network-diagram.svg
|
203
234
|
[fenced]: https://www.markdownguide.org/extended-syntax/#syntax-highlighting
|
204
235
|
[fork]: https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo
|
205
236
|
[gem-badge]: https://badge.fury.io/rb/kramdown-plantuml.svg
|
Binary file
|
data/kramdown-plantuml.gemspec
CHANGED
@@ -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 #{
|
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
|
|
@@ -1,14 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'log_wrapper'
|
4
|
-
require_relative 'jekyll_page_processor'
|
5
4
|
|
6
5
|
module Kramdown
|
7
6
|
module PlantUml
|
8
7
|
# Provides an instance of Jekyll if available.
|
9
8
|
module JekyllProvider
|
10
9
|
class << self
|
11
|
-
attr_reader :
|
10
|
+
attr_reader :site_source_dir
|
12
11
|
|
13
12
|
def jekyll
|
14
13
|
return @jekyll if defined? @jekyll
|
@@ -16,52 +15,17 @@ module Kramdown
|
|
16
15
|
@jekyll = load_jekyll
|
17
16
|
end
|
18
17
|
|
19
|
-
def install
|
20
|
-
return @installed = false if jekyll.nil?
|
21
|
-
|
22
|
-
find_site_destination_dir
|
23
|
-
register_hook
|
24
|
-
@installed = true
|
25
|
-
end
|
26
|
-
|
27
|
-
def installed?
|
28
|
-
@installed
|
29
|
-
end
|
30
|
-
|
31
|
-
def needle(plantuml, options)
|
32
|
-
JekyllPageProcessor.needle(plantuml, options)
|
33
|
-
end
|
34
|
-
|
35
18
|
private
|
36
19
|
|
37
|
-
def
|
20
|
+
def find_site_source_dir
|
38
21
|
if jekyll.sites.nil? || jekyll.sites.empty?
|
39
|
-
logger.
|
22
|
+
logger.warn 'Jekyll detected, but no sites found.'
|
40
23
|
return nil
|
41
24
|
end
|
42
25
|
|
43
|
-
@
|
44
|
-
logger.debug "Jekyll detected,
|
45
|
-
@
|
46
|
-
end
|
47
|
-
|
48
|
-
def register_hook
|
49
|
-
Jekyll::Hooks.register :site, :post_write do |site|
|
50
|
-
site_post_write(site)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def site_post_write(site)
|
55
|
-
logger.debug 'Jekyll:site:post_write triggered.'
|
56
|
-
@site_destination_dir ||= site.dest
|
57
|
-
|
58
|
-
site.pages.each do |page|
|
59
|
-
processor = JekyllPageProcessor.new(page)
|
60
|
-
|
61
|
-
next unless processor.should_process?
|
62
|
-
|
63
|
-
processor.process(site.dest)
|
64
|
-
end
|
26
|
+
@site_source_dir = jekyll.sites.first.source
|
27
|
+
logger.debug "Jekyll detected, using '#{@site_source_dir}' as base directory."
|
28
|
+
@site_source_dir
|
65
29
|
end
|
66
30
|
|
67
31
|
def load_jekyll
|
@@ -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, :scale
|
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,24 @@ 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
|
+
set_instance_property(:scale, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def set_instance_property(key, options)
|
79
|
+
return unless options.key? key
|
80
|
+
|
81
|
+
value = options[key]
|
82
|
+
value = :none if value.none_s?
|
83
|
+
prop_name = "@#{key}".to_sym
|
84
|
+
instance_variable_set(prop_name, value)
|
85
|
+
end
|
86
|
+
|
67
87
|
def massage(options_hash)
|
68
88
|
if options_hash.nil? || !options_hash.is_a?(Hash) || options_hash.empty?
|
69
89
|
@logger.debug 'No options provided'
|
@@ -1,23 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
3
|
+
require_relative 'executor'
|
4
|
+
require_relative 'log_wrapper'
|
5
5
|
require_relative 'options'
|
6
6
|
require_relative 'plantuml_error'
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
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
|
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?
|
18
19
|
raise ArgumentError, "options must be a '#{Options}'." unless options.is_a?(Options)
|
19
20
|
|
20
|
-
@plantuml = plantuml
|
21
|
+
@plantuml = plantuml.strip unless plantuml.nil?
|
21
22
|
@options = options
|
22
23
|
@theme = Theme.new(options)
|
23
24
|
@logger = LogWrapper.init
|
@@ -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
|
29
|
-
return @
|
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
|
-
log(plantuml)
|
33
|
+
log(@plantuml)
|
34
34
|
@result = @executor.execute(self)
|
35
|
-
@result
|
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.
|
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.
|
38
|
-
'#{result.
|
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.
|
53
|
+
return nil if result.nil? || result.plantuml_diagram.nil?
|
54
54
|
|
55
|
-
result.
|
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 '
|
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 :
|
11
|
+
attr_reader :plantuml_diagram, :stdout, :stderr, :exitcode
|
12
12
|
|
13
|
-
def initialize(
|
14
|
-
raise ArgumentError, 'diagram cannot be nil' if
|
15
|
-
raise ArgumentError, "diagram must be a #{
|
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
|
-
@
|
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
|
27
|
-
|
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
|
@@ -8,7 +8,7 @@ module Kramdown
|
|
8
8
|
module PlantUml
|
9
9
|
# Provides theming support for PlantUML
|
10
10
|
class Theme
|
11
|
-
attr_reader :name, :directory
|
11
|
+
attr_reader :name, :directory, :scale
|
12
12
|
|
13
13
|
def initialize(options)
|
14
14
|
raise ArgumentError, 'options cannot be nil' if options.nil?
|
@@ -17,6 +17,7 @@ module Kramdown
|
|
17
17
|
@raise_errors = options.raise_errors?
|
18
18
|
@logger = LogWrapper.init
|
19
19
|
@name = options.theme_name
|
20
|
+
@scale = options.scale
|
20
21
|
@directory = resolve options.theme_directory
|
21
22
|
end
|
22
23
|
|
@@ -26,11 +27,6 @@ module Kramdown
|
|
26
27
|
return plantuml
|
27
28
|
end
|
28
29
|
|
29
|
-
if @name.nil? || @name.empty?
|
30
|
-
@logger.debug 'No theme to apply.'
|
31
|
-
return plantuml.strip
|
32
|
-
end
|
33
|
-
|
34
30
|
theme(plantuml)
|
35
31
|
end
|
36
32
|
|
@@ -39,9 +35,9 @@ module Kramdown
|
|
39
35
|
def resolve(directory)
|
40
36
|
jekyll = JekyllProvider
|
41
37
|
|
42
|
-
return directory if directory.nil? || directory.empty?
|
38
|
+
return directory if directory.nil? || directory.empty?
|
43
39
|
|
44
|
-
directory = File.absolute_path(directory, jekyll.
|
40
|
+
directory = File.absolute_path(directory, jekyll.site_source_dir)
|
45
41
|
|
46
42
|
log_or_raise "The theme directory '#{directory}' cannot be found" unless Dir.exist?(directory)
|
47
43
|
|
@@ -55,17 +51,16 @@ module Kramdown
|
|
55
51
|
def log_or_raise(message)
|
56
52
|
raise IOError, message if @raise_errors
|
57
53
|
|
58
|
-
logger.warn message
|
54
|
+
@logger.warn message
|
59
55
|
end
|
60
56
|
|
61
57
|
def theme(plantuml)
|
62
|
-
|
63
|
-
startuml_index = plantuml.index(startuml) + startuml.length
|
58
|
+
theme_string = build_theme_string
|
64
59
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
60
|
+
if theme_string.empty?
|
61
|
+
@logger.debug 'No theme to apply.'
|
62
|
+
return plantuml
|
63
|
+
end
|
69
64
|
|
70
65
|
@logger.debug "Applying #{theme_string.strip}"
|
71
66
|
|
@@ -75,6 +70,18 @@ module Kramdown
|
|
75
70
|
|
76
71
|
plantuml.strip
|
77
72
|
end
|
73
|
+
|
74
|
+
def build_theme_string
|
75
|
+
theme_string = ''
|
76
|
+
|
77
|
+
unless @name.nil? || @name.empty?
|
78
|
+
theme_string << "\n!theme #{@name}"
|
79
|
+
theme_string << " from #{@directory}" unless @directory.nil?
|
80
|
+
end
|
81
|
+
|
82
|
+
theme_string << "\nscale #{@scale}" unless @scale.nil?
|
83
|
+
theme_string
|
84
|
+
end
|
78
85
|
end
|
79
86
|
end
|
80
87
|
end
|
data/lib/kramdown-plantuml.rb
CHANGED
data/lib/kramdown_html.rb
CHANGED
@@ -5,8 +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/
|
9
|
-
require_relative 'kramdown-plantuml/jekyll_provider'
|
8
|
+
require_relative 'kramdown-plantuml/plantuml_diagram'
|
10
9
|
|
11
10
|
module Kramdown
|
12
11
|
module Converter
|
@@ -16,19 +15,9 @@ module Kramdown
|
|
16
15
|
alias super_convert_codeblock convert_codeblock
|
17
16
|
|
18
17
|
def convert_codeblock(element, indent)
|
19
|
-
return super_convert_codeblock(element, indent) unless plantuml?
|
18
|
+
return super_convert_codeblock(element, indent) unless plantuml? element
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
# If Jekyll is successfully loaded, we'll wait with converting the
|
24
|
-
# PlantUML diagram to SVG since a theme may be configured that needs to
|
25
|
-
# be copied to the assets directory before the PlantUML conversion can
|
26
|
-
# be performed. We therefore place a needle in the haystack that we will
|
27
|
-
# convert in the :site:pre_render hook.
|
28
|
-
options = ::Kramdown::PlantUml::Options.new(@options)
|
29
|
-
return jekyll.needle(element.value, options) if jekyll.installed?
|
30
|
-
|
31
|
-
convert_plantuml(element.value, options)
|
20
|
+
convert_plantuml(element.value)
|
32
21
|
end
|
33
22
|
|
34
23
|
private
|
@@ -37,14 +26,15 @@ module Kramdown
|
|
37
26
|
element.attr['class'] == 'language-plantuml'
|
38
27
|
end
|
39
28
|
|
40
|
-
def convert_plantuml(plantuml
|
41
|
-
|
42
|
-
diagram.
|
29
|
+
def convert_plantuml(plantuml)
|
30
|
+
puml_opts = ::Kramdown::PlantUml::Options.new(@options)
|
31
|
+
diagram = ::Kramdown::PlantUml::PlantUmlDiagram.new(plantuml, puml_opts)
|
32
|
+
diagram.svg.to_s
|
43
33
|
rescue StandardError => e
|
44
|
-
raise e if
|
34
|
+
raise e if puml_opts.nil? || puml_opts.raise_errors?
|
45
35
|
|
46
36
|
logger = ::Kramdown::PlantUml::LogWrapper.init
|
47
|
-
logger.error "Error while
|
37
|
+
logger.error "Error while converting diagram: #{e.inspect}"
|
48
38
|
end
|
49
39
|
end
|
50
40
|
end
|
data/pom.xml
CHANGED
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.
|
4
|
+
version: 1.3.2
|
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
|
+
date: 2021-12-13 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,21 @@ files:
|
|
180
194
|
- LICENSE
|
181
195
|
- README.md
|
182
196
|
- Rakefile
|
183
|
-
- bin/net/sourceforge/plantuml/plantuml/1.2021.
|
197
|
+
- bin/net/sourceforge/plantuml/plantuml/1.2021.16/plantuml-1.2021.16.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
|
-
- lib/kramdown-plantuml/jekyll_page_processor.rb
|
191
203
|
- lib/kramdown-plantuml/jekyll_provider.rb
|
192
204
|
- lib/kramdown-plantuml/log_wrapper.rb
|
205
|
+
- lib/kramdown-plantuml/none_s.rb
|
193
206
|
- lib/kramdown-plantuml/options.rb
|
207
|
+
- lib/kramdown-plantuml/plantuml_diagram.rb
|
194
208
|
- lib/kramdown-plantuml/plantuml_error.rb
|
195
209
|
- lib/kramdown-plantuml/plantuml_result.rb
|
210
|
+
- lib/kramdown-plantuml/style_builder.rb
|
211
|
+
- lib/kramdown-plantuml/svg_diagram.rb
|
196
212
|
- lib/kramdown-plantuml/theme.rb
|
197
213
|
- lib/kramdown-plantuml/version.rb
|
198
214
|
- lib/kramdown-plantuml/which.rb
|
@@ -1,103 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'htmlentities'
|
4
|
-
require 'json'
|
5
|
-
require_relative 'log_wrapper'
|
6
|
-
|
7
|
-
module Kramdown
|
8
|
-
module PlantUml
|
9
|
-
# Processes Jekyll pages.
|
10
|
-
class JekyllPageProcessor
|
11
|
-
PROCESSED_KEY = :kramdown_plantuml_processed
|
12
|
-
|
13
|
-
def initialize(page)
|
14
|
-
raise ArgumentError, 'page cannot be nil' if page.nil?
|
15
|
-
|
16
|
-
@page = page
|
17
|
-
end
|
18
|
-
|
19
|
-
def process(site_destination_directory)
|
20
|
-
@page.output = do_process
|
21
|
-
@page.data[PROCESSED_KEY] = true
|
22
|
-
@page.write(site_destination_directory)
|
23
|
-
end
|
24
|
-
|
25
|
-
def should_process?
|
26
|
-
return false unless @page.output_ext == '.html'
|
27
|
-
|
28
|
-
if !@page.data.nil? && @page.data.key?(PROCESSED_KEY) && @page.data[PROCESSED_KEY]
|
29
|
-
logger.debug "Skipping #{@page.path} because it has already been processed."
|
30
|
-
return false
|
31
|
-
end
|
32
|
-
|
33
|
-
true
|
34
|
-
end
|
35
|
-
|
36
|
-
class << self
|
37
|
-
def needle(plantuml, options)
|
38
|
-
hash = { 'plantuml' => plantuml, 'options' => options.to_h }
|
39
|
-
|
40
|
-
<<~NEEDLE
|
41
|
-
<!--#kramdown-plantuml.start#-->
|
42
|
-
#{hash.to_json}
|
43
|
-
<!--#kramdown-plantuml.end#-->
|
44
|
-
NEEDLE
|
45
|
-
rescue StandardError => e
|
46
|
-
raise e if options.nil? || options.raise_errors?
|
47
|
-
|
48
|
-
logger.error 'Error while placing needle.'
|
49
|
-
logger.error e.to_s
|
50
|
-
logger.debug_multiline plantuml
|
51
|
-
end
|
52
|
-
|
53
|
-
def logger
|
54
|
-
@logger ||= ::Kramdown::PlantUml::LogWrapper.init
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def do_process
|
61
|
-
logger.debug "Replacing Jekyll needles in #{@page.path}"
|
62
|
-
|
63
|
-
html = @page.output
|
64
|
-
|
65
|
-
return html if html.nil? || html.empty? || !html.is_a?(String)
|
66
|
-
|
67
|
-
html.gsub(/<!--#kramdown-plantuml\.start#-->(?<json>.*?)<!--#kramdown-plantuml\.end#-->/m) do
|
68
|
-
json = $LAST_MATCH_INFO ? $LAST_MATCH_INFO[:json] : nil
|
69
|
-
replace_needle(json) unless json.nil?
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def replace_needle(json)
|
74
|
-
logger.debug 'Replacing Jekyll needle.'
|
75
|
-
|
76
|
-
needle_hash = JSON.parse(json)
|
77
|
-
options_hash = needle_hash['options']
|
78
|
-
options = ::Kramdown::PlantUml::Options.new({ plantuml: options_hash })
|
79
|
-
|
80
|
-
begin
|
81
|
-
decode_and_convert(needle_hash, options)
|
82
|
-
rescue StandardError => e
|
83
|
-
raise e if options.raise_errors?
|
84
|
-
|
85
|
-
logger.error 'Error while replacing Jekyll needle.'
|
86
|
-
logger.error e.to_s
|
87
|
-
logger.debug_multiline json
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def decode_and_convert(hash, options)
|
92
|
-
encoded_plantuml = hash['plantuml']
|
93
|
-
plantuml = HTMLEntities.new.decode encoded_plantuml
|
94
|
-
diagram = ::Kramdown::PlantUml::Diagram.new(plantuml, options)
|
95
|
-
diagram.convert_to_svg
|
96
|
-
end
|
97
|
-
|
98
|
-
def logger
|
99
|
-
@logger ||= ::Kramdown::PlantUml::LogWrapper.init
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|