asciidoctor-plantuml 0.0.9 → 0.0.10

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: 9e836d29f06c357381929224f4c3c344aa1eea0288ac5aff95b391898ffd0e80
4
- data.tar.gz: e02e8fa50763daa1c78d86e8a9c4af7be72905c45de61ae4c60b8d7bf9e3a3fb
3
+ metadata.gz: 368d0190d9b9251c4a9794b9cd44ce6928cf8f963da4816d2a644d9f79bf5219
4
+ data.tar.gz: d5b7d4fc0527d9651770859163a18445e929616debfa1e3272864cd2a1dd2904
5
5
  SHA512:
6
- metadata.gz: 40d310baa03ed8f773d457bdde42ed92e7ef387c1bde39ef37475117a95b8c2544f7cf7420623491fbcbf0fcd024f03c8ad4139289728a7b4e010033ddea0853
7
- data.tar.gz: 1ca5d165518845bc57f5c0ddb8fbdddbcb52127faa950ebe51b551cd1a4604576409d6562a5035ec3dbbeb4f3c2577e1937a33446b4b38aff913b62fc2836551
6
+ metadata.gz: '0004181c00fa36e64b216dadf7b2b04f4fea160cb2b7795ad516458757b02e50c226da6a05e58644d4467e9df09c62004baf7c09797f7365bc9533b1a303cb86'
7
+ data.tar.gz: 61625a5f4c1c753158567c12a85f18c62763ccd434270dc2f4bc65273fcefe830af209b7d1e4f07a30ec2bdb9069b64c78aaf28b37520fe2b5b7eb00c553ba26
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'asciidoctor'
2
4
  require 'asciidoctor/extensions'
3
- require_relative 'asciidoctor-plantuml/plantuml'
5
+ require_relative 'asciidoctor_plantuml/plantuml'
4
6
 
5
7
  Asciidoctor::Extensions.register do
6
8
  block Asciidoctor::PlantUml::BlockProcessor, :plantuml
@@ -0,0 +1,271 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'open-uri'
5
+ require 'zlib'
6
+ require 'open-uri'
7
+ require 'net/http'
8
+
9
+ module Asciidoctor
10
+ # PlantUML Module
11
+ module PlantUml
12
+ # PlantUML Configuration
13
+ class Configuration
14
+ DEFAULT_URL = ENV['PLANTUML_URL'] || ''
15
+
16
+ attr_accessor :url, :txt_enable, :svg_enable, :png_enable
17
+
18
+ def initialize
19
+ @url = DEFAULT_URL
20
+ @txt_enable = true
21
+ @svg_enable = true
22
+ @png_enable = true
23
+ end
24
+ end
25
+
26
+ class << self
27
+ attr_writer :configuration
28
+ end
29
+
30
+ def self.configuration
31
+ @configuration ||= Configuration.new
32
+ end
33
+
34
+ def self.configure
35
+ yield(configuration)
36
+ end
37
+
38
+ # PlantUML Processor
39
+ class Processor
40
+ FORMATS = %w[png svg txt].freeze
41
+ DEFAULT_FORMAT = FORMATS[0]
42
+
43
+ class << self
44
+ def valid_format?(format)
45
+ FORMATS.include?(format)
46
+ end
47
+
48
+ def server_url
49
+ PlantUml.configuration.url
50
+ end
51
+
52
+ def txt_enabled?
53
+ PlantUml.configuration.txt_enable
54
+ end
55
+
56
+ def png_enabled?
57
+ PlantUml.configuration.png_enable
58
+ end
59
+
60
+ def svg_enabled?
61
+ PlantUml.configuration.svg_enable
62
+ end
63
+
64
+ def enabled?
65
+ txt_enabled? || png_enabled? || svg_enabled?
66
+ end
67
+
68
+ def plantuml_content_format(code, format, attrs = {})
69
+ if %w[png svg].include?(format)
70
+ plantuml_img_content(code, format, attrs)
71
+ elsif format == 'txt' && txt_enabled?
72
+ plantuml_txt_content(code, format, attrs)
73
+ else
74
+ plantuml_invalid_content(format, attrs)
75
+ end
76
+ end
77
+
78
+ def plantuml_content(code, attrs = {})
79
+ format = attrs['format'] || DEFAULT_FORMAT
80
+
81
+ return plantuml_disabled_content(code, attrs) unless enabled?
82
+
83
+ unless valid_uri?(server_url)
84
+ return plantuml_server_unavailable_content(server_url, attrs)
85
+ end
86
+
87
+ plantuml_content_format(code, format, attrs)
88
+ end
89
+
90
+ # Compression code used to generate PlantUML URLs. Taken directly from
91
+ # the transcoder class in the PlantUML java code.
92
+ def gen_url(text, format)
93
+ result = ''
94
+ compressed_data = Zlib::Deflate.deflate(text)
95
+ compressed_data.chars.each_slice(3) do |bytes|
96
+ # print bytes[0], ' ' , bytes[1] , ' ' , bytes[2]
97
+ b1 = bytes[0].nil? ? 0 : (bytes[0].ord & 0xFF)
98
+ b2 = bytes[1].nil? ? 0 : (bytes[1].ord & 0xFF)
99
+ b3 = bytes[2].nil? ? 0 : (bytes[2].ord & 0xFF)
100
+ result += append3bytes(b1, b2, b3)
101
+ end
102
+ join_paths(server_url, "#{format}/", result).to_s
103
+ end
104
+
105
+ private
106
+
107
+ def plantuml_txt_content(code, format, attrs = {})
108
+ url = gen_url(code, format)
109
+ URI(url).open do |f|
110
+ plantuml_ascii_content(f.read, attrs)
111
+ end
112
+ rescue OpenURI::HTTPError, Errno::ECONNREFUSED, SocketError
113
+ plantuml_img_content(code, format, attrs)
114
+ end
115
+
116
+ def plantuml_ascii_content(code, attrs = {})
117
+ content = '<div class="listingblock">'
118
+ content += '<div class="content">'
119
+ content += '<pre '
120
+ content += "id=\"#{attrs['id']}\" " if attrs['id']
121
+ content += 'class="plantuml">\n'
122
+ content += code
123
+ content += '</pre>'
124
+ content += '</div>'
125
+ content + '</div>'
126
+ end
127
+
128
+ def plantuml_img_content(code, format, attrs = {})
129
+ content = '<div class="imageblock">'
130
+ content += '<div class="content">'
131
+ content += '<img '
132
+ content += "id=\"#{attrs['id']}\" " if attrs['id']
133
+ content += 'class="plantuml" '
134
+ content += "width=\"#{attrs['width']}\" " if attrs['width']
135
+ content += "height=\"#{attrs['height']}\" " if attrs['height']
136
+ content += "alt=\"#{attrs['alt']}\" " if attrs['alt']
137
+ content += "src=\"#{gen_url(code, format)}\" />"
138
+ content += '</div>'
139
+ content + '</div>'
140
+ end
141
+
142
+ def plantuml_invalid_content(format, attrs = {})
143
+ content = '<div class="listingblock">'
144
+ content += '<div class="content">'
145
+ content += '<pre '
146
+ content += "id=\"#{attrs['id']}\" " if attrs['id']
147
+ content += 'class="plantuml plantuml-error"> '
148
+ content += "PlantUML Error: Invalid format \"#{format}\""
149
+ content += '</pre>'
150
+ content += '</div>'
151
+ content + '</div>'
152
+ end
153
+
154
+ def plantuml_server_unavailable_content(url, attrs = {})
155
+ content = '<div class="listingblock">'
156
+ content += '<div class="content">'
157
+ content += '<pre '
158
+ content += "id=\"#{attrs['id']}\" " if attrs['id']
159
+ content += 'class="plantuml plantuml-error"> '
160
+ content += "Error: cannot connect to PlantUML server at \"#{url}\""
161
+ content += '</pre>'
162
+ content += '</div>'
163
+ content + '</div>'
164
+ end
165
+
166
+ def plantuml_disabled_content(code, attrs = {})
167
+ content = '<div class="listingblock">'
168
+ content += '<div class="content">'
169
+ content += '<pre '
170
+ content += "id=\"#{attrs['id']}\" " if attrs['id']
171
+ content += 'class="plantuml plantuml-error">\n'
172
+ content += code
173
+ content += '</pre>'
174
+ content += '</div>'
175
+ content + '</div>'
176
+ end
177
+
178
+ def encode6bit(bit)
179
+ return ('0'.ord + bit).chr if bit < 10
180
+
181
+ bit -= 10
182
+ return ('A'.ord + bit).chr if bit < 26
183
+
184
+ bit -= 26
185
+ return ('a'.ord + bit).chr if bit < 26
186
+
187
+ bit -= 26
188
+ return '-' if bit.zero?
189
+
190
+ return '_' if bit == 1
191
+
192
+ '?'
193
+ end
194
+
195
+ def append3bytes(bit1, bit2, bit3)
196
+ c1 = bit1 >> 2
197
+ c2 = ((bit1 & 0x3) << 4) | (bit2 >> 4)
198
+ c3 = ((bit2 & 0xF) << 2) | (bit3 >> 6)
199
+ c4 = bit3 & 0x3F
200
+ encode6bit(c1 & 0x3F).chr +
201
+ encode6bit(c2 & 0x3F).chr +
202
+ encode6bit(c3 & 0x3F).chr +
203
+ encode6bit(c4 & 0x3F).chr
204
+ end
205
+
206
+ # Make a call to the PlantUML server with the simplest diagram possible
207
+ # to check if the server is available or not.
208
+ def check_server(check_url)
209
+ response = Net::HTTP.get_response(URI(check_url))
210
+ response.is_a?(Net::HTTPSuccess)
211
+ rescue OpenURI::HTTPError, Errno::ECONNREFUSED, SocketError
212
+ false
213
+ end
214
+
215
+ def valid_uri?(uri)
216
+ !(uri =~ /\A#{URI.regexp(%w[http https])}\z/).nil?
217
+ end
218
+
219
+ def join_paths(*paths, separator: '/')
220
+ paths = paths.compact.reject(&:empty?)
221
+ last = paths.length - 1
222
+ paths.each_with_index.map do |path, index|
223
+ expand_path(path, index, last, separator)
224
+ end.join
225
+ end
226
+
227
+ def expand_path(path, current, last, separator)
228
+ path = path[1..-1] if path.start_with?(separator) && current.zero?
229
+
230
+ unless path.end_with?(separator) || current == last
231
+ path = [path, separator]
232
+ end
233
+
234
+ path
235
+ end
236
+ end
237
+ end
238
+
239
+ # PlantUML BlockProcessor
240
+ class BlockProcessor < Asciidoctor::Extensions::BlockProcessor
241
+ use_dsl
242
+ named :plantuml
243
+ on_context :listing
244
+ content_model :simple
245
+
246
+ def process(parent, target, attrs)
247
+ lines = target.lines
248
+
249
+ unless target.lines[0] =~ /@startuml/
250
+ lines = ['@startuml'] + target.lines
251
+ end
252
+
253
+ lines += ['@enduml'] unless target.lines[-1] =~ /@enduml/
254
+
255
+ content = Processor.plantuml_content(lines.join("\n"), attrs)
256
+
257
+ create_plantuml_block(parent, content, attrs)
258
+ end
259
+
260
+ private
261
+
262
+ def create_plantuml_block(parent, content, attrs)
263
+ Asciidoctor::Block.new parent, :pass, {
264
+ content_model: :raw,
265
+ source: content,
266
+ subs: :default
267
+ }.merge(attrs)
268
+ end
269
+ end
270
+ end
271
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module PlantUML
5
+ VERSION = '0.0.10'
6
+ end
7
+ end
@@ -1,133 +1,133 @@
1
- require "test/unit"
2
- require "asciidoctor"
3
- require "stringio"
4
- require "nokogiri"
5
- require "asciidoctor-plantuml"
6
-
7
- DOC_BASIC = <<-eos
8
- = Hello PlantUML!
9
-
10
- [plantuml, format="png"]
11
- .Title Of this
12
- ----
13
- User -> (Start)
14
- User --> (Use the application) : Label
15
- ----
16
- eos
17
-
18
- DOC_BASIC2 = <<-eos
19
- = Hello PlantUML!
20
-
21
- [plantuml, format="png"]
22
- .Title Of this
23
- [[fig-xref]]
24
- ----
25
- @startuml
26
- User -> (Start)
27
- User --> (Use the application) : Label
28
- @enduml
29
- ----
30
- eos
31
-
32
- DOC_BASIC3 = <<-eos
33
- = Hello Compound PlantUML!
34
-
35
- [plantuml, format="png"]
36
- ----
37
- [COMP1]
38
- [COMP2]
39
- [COMP1] -> [COMP2]
40
- [COMP2] --> [COMP3]
41
- ----
42
- eos
43
-
44
- DOC_ID = <<-eos
45
- = Hello PlantUML!
46
-
47
- [plantuml, format="png", id="myId"]
48
- ----
49
- User -> (Start)
50
- User --> (Use the application) : Label
51
- ----
52
- eos
53
-
54
- DOC_DIM = <<-eos
55
- = Hello PlantUML!
56
-
57
- [plantuml, format="png", width="100px", height="50px"]
58
- ----
59
- User -> (Start)
60
- User --> (Use the application) : Label
61
- ----
62
- eos
63
-
64
- DOC_ALT = <<-eos
65
- = Hello PlantUML!
66
-
67
- [plantuml, format="png", alt="alt"]
68
- ----
69
- User -> (Start)
70
- User --> (Use the application) : Label
71
- ----
72
- eos
73
-
74
- DOC_BAD_FORMAT = <<-eos
75
- = Hello PlantUML!
76
-
77
- [plantuml, format="jpg"]
78
- ----
79
- User -> (Start)
80
- User --> (Use the application) : Label
81
- ----
82
- eos
83
-
84
- DOC_MULTI = <<-eos
85
- = Hello PlantUML!
86
-
87
- [plantuml, format="png"]
88
- ----
89
- User -> (Start)
90
- User --> (Use the application) : Label
91
- ----
92
-
93
- [plantuml, format="png"]
94
- ----
95
- User -> (Start)
96
- User --> (Use the application) : Label
97
- ----
98
-
99
- [plantuml, format="txt"]
100
- ----
101
- User -> (Start)
102
- User --> (Use the application) : Label
103
- ----
104
- eos
105
-
106
- DOC_TXT = <<-eos
107
- = Hello PlantUML!
108
-
109
- [plantuml, format="txt"]
110
- ----
111
- User -> (Start)
112
- User --> (Use the application) : Label
113
- ----
114
- eos
1
+ # frozen_string_literal: true
2
+
3
+ require 'test/unit'
4
+ require 'asciidoctor'
5
+ require 'stringio'
6
+ require 'nokogiri'
7
+ require 'asciidoctor-plantuml'
8
+
9
+ DOC_BASIC = <<~ENDOFSTRING
10
+ = Hello PlantUML!
11
+
12
+ [plantuml, format="png"]
13
+ .Title Of this
14
+ ----
15
+ User -> (Start)
16
+ User --> (Use the application) : Label
17
+ ----
18
+ ENDOFSTRING
19
+
20
+ DOC_BASIC2 = <<~ENDOFSTRING
21
+ = Hello PlantUML!
22
+
23
+ [plantuml, format="png"]
24
+ .Title Of this
25
+ [[fig-xref]]
26
+ ----
27
+ @startuml
28
+ User -> (Start)
29
+ User --> (Use the application) : Label
30
+ @enduml
31
+ ----
32
+ ENDOFSTRING
33
+
34
+ DOC_BASIC3 = <<~ENDOFSTRING
35
+ = Hello Compound PlantUML!
36
+
37
+ [plantuml, format="png"]
38
+ ----
39
+ [COMP1]
40
+ [COMP2]
41
+ [COMP1] -> [COMP2]
42
+ [COMP2] --> [COMP3]
43
+ ----
44
+ ENDOFSTRING
45
+
46
+ DOC_ID = <<~ENDOFSTRING
47
+ = Hello PlantUML!
48
+
49
+ [plantuml, format="png", id="myId"]
50
+ ----
51
+ User -> (Start)
52
+ User --> (Use the application) : Label
53
+ ----
54
+ ENDOFSTRING
55
+
56
+ DOC_DIM = <<~ENDOFSTRING
57
+ = Hello PlantUML!
58
+
59
+ [plantuml, format="png", width="100px", height="50px"]
60
+ ----
61
+ User -> (Start)
62
+ User --> (Use the application) : Label
63
+ ----
64
+ ENDOFSTRING
65
+
66
+ DOC_ALT = <<~ENDOFSTRING
67
+ = Hello PlantUML!
68
+
69
+ [plantuml, format="png", alt="alt"]
70
+ ----
71
+ User -> (Start)
72
+ User --> (Use the application) : Label
73
+ ----
74
+ ENDOFSTRING
75
+
76
+ DOC_BAD_FORMAT = <<~ENDOFSTRING
77
+ = Hello PlantUML!
78
+
79
+ [plantuml, format="jpg"]
80
+ ----
81
+ User -> (Start)
82
+ User --> (Use the application) : Label
83
+ ----
84
+ ENDOFSTRING
85
+
86
+ DOC_MULTI = <<~ENDOFSTRING
87
+ = Hello PlantUML!
88
+
89
+ [plantuml, format="png"]
90
+ ----
91
+ User -> (Start)
92
+ User --> (Use the application) : Label
93
+ ----
94
+
95
+ [plantuml, format="png"]
96
+ ----
97
+ User -> (Start)
98
+ User --> (Use the application) : Label
99
+ ----
100
+
101
+ [plantuml, format="txt"]
102
+ ----
103
+ User -> (Start)
104
+ User --> (Use the application) : Label
105
+ ----
106
+ ENDOFSTRING
107
+
108
+ DOC_TXT = <<~ENDOFSTRING
109
+ = Hello PlantUML!
110
+
111
+ [plantuml, format="txt"]
112
+ ----
113
+ User -> (Start)
114
+ User --> (Use the application) : Label
115
+ ----
116
+ ENDOFSTRING
115
117
 
116
118
  class PlantUmlTest < Test::Unit::TestCase
117
-
118
- GENURL = "http://localhost:8080/plantuml/png/U9npA2v9B2efpStX2YrEBLBGjLFG20Q9Q4Bv804WIw4a8rKXiQ0W9pCviIGpFqzJmKh19p4fDOVB8JKl1QWT05kd5wq0"
119
- GENURL2 = "http://localhost:8080/plantuml/png/U9npA2v9B2efpStXYdRszmqmZ8NGHh4mleAkdGAAa15G22Pc7Clba9gN0jGE00W75Cm0"
119
+ GENURL = 'http://localhost:8080/plantuml/png/U9npA2v9B2efpStX2YrEBLBGjLFG20Q9Q4Bv804WIw4a8rKXiQ0W9pCviIGpFqzJmKh19p4fDOVB8JKl1QWT05kd5wq0'
120
+ GENURL2 = 'http://localhost:8080/plantuml/png/U9npA2v9B2efpStXYdRszmqmZ8NGHh4mleAkdGAAa15G22Pc7Clba9gN0jGE00W75Cm0'
120
121
 
121
122
  def setup
122
123
  Asciidoctor::PlantUml.configure do |c|
123
- c.url = "http://localhost:8080/plantuml"
124
+ c.url = 'http://localhost:8080/plantuml'
124
125
  c.txt_enable = true
125
126
  end
126
127
  end
127
128
 
128
129
  def test_plantuml_block_processor
129
-
130
- html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: "html5")
130
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: 'html5')
131
131
  page = Nokogiri::HTML(html)
132
132
 
133
133
  elements = page.css('img.plantuml')
@@ -136,11 +136,11 @@ class PlantUmlTest < Test::Unit::TestCase
136
136
 
137
137
  element = elements.first
138
138
 
139
- assert_equal GENURL, element["src"]
139
+ assert_equal GENURL, element['src']
140
140
  end
141
141
 
142
142
  def test_plantuml_block_processor2
143
- html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC2), backend: "html5")
143
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC2), backend: 'html5')
144
144
  page = Nokogiri::HTML(html)
145
145
 
146
146
  elements = page.css('img.plantuml')
@@ -149,11 +149,11 @@ class PlantUmlTest < Test::Unit::TestCase
149
149
 
150
150
  element = elements.first
151
151
 
152
- assert_equal GENURL, element["src"]
152
+ assert_equal GENURL, element['src']
153
153
  end
154
154
 
155
155
  def test_plantuml_block_processor3
156
- html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC3), backend: "html5")
156
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC3), backend: 'html5')
157
157
  page = Nokogiri::HTML(html)
158
158
 
159
159
  elements = page.css('img.plantuml')
@@ -162,12 +162,11 @@ class PlantUmlTest < Test::Unit::TestCase
162
162
 
163
163
  element = elements.first
164
164
 
165
- assert_equal GENURL2, element["src"]
165
+ assert_equal GENURL2, element['src']
166
166
  end
167
167
 
168
168
  def test_plantuml_id_attribute
169
-
170
- html = ::Asciidoctor.convert(StringIO.new(DOC_ID), backend: "html5")
169
+ html = ::Asciidoctor.convert(StringIO.new(DOC_ID), backend: 'html5')
171
170
  page = Nokogiri::HTML(html)
172
171
 
173
172
  elements = page.css('img.plantuml')
@@ -175,13 +174,11 @@ class PlantUmlTest < Test::Unit::TestCase
175
174
  assert_equal elements.size, 1
176
175
  element = elements.first
177
176
 
178
- assert_equal "myId", element["id"]
179
-
177
+ assert_equal 'myId', element['id']
180
178
  end
181
179
 
182
180
  def test_plantuml_dimension_attribute
183
-
184
- html = ::Asciidoctor.convert(StringIO.new(DOC_DIM), backend: "html5")
181
+ html = ::Asciidoctor.convert(StringIO.new(DOC_DIM), backend: 'html5')
185
182
  page = Nokogiri::HTML(html)
186
183
 
187
184
  elements = page.css('img.plantuml')
@@ -189,14 +186,12 @@ class PlantUmlTest < Test::Unit::TestCase
189
186
  assert_equal elements.size, 1
190
187
  element = elements.first
191
188
 
192
- assert_equal "100px", element["width"]
193
- assert_equal "50px", element["height"]
194
-
189
+ assert_equal '100px', element['width']
190
+ assert_equal '50px', element['height']
195
191
  end
196
192
 
197
193
  def test_plantuml_alt_attribute
198
-
199
- html = ::Asciidoctor.convert(StringIO.new(DOC_ALT), backend: "html5")
194
+ html = ::Asciidoctor.convert(StringIO.new(DOC_ALT), backend: 'html5')
200
195
  page = Nokogiri::HTML(html)
201
196
 
202
197
  elements = page.css('img.plantuml')
@@ -204,23 +199,20 @@ class PlantUmlTest < Test::Unit::TestCase
204
199
  assert_equal elements.size, 1
205
200
  element = elements.first
206
201
 
207
- assert_equal "alt", element["alt"]
208
-
202
+ assert_equal 'alt', element['alt']
209
203
  end
210
204
 
211
205
  def test_should_show_bad_format
212
- html = ::Asciidoctor.convert(StringIO.new(DOC_BAD_FORMAT), backend: "html5")
206
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BAD_FORMAT), backend: 'html5')
213
207
 
214
208
  page = Nokogiri::HTML(html)
215
209
 
216
210
  elements = page.css('pre.plantuml-error')
217
211
  assert_equal elements.size, 1
218
-
219
212
  end
220
213
 
221
214
  def test_plantuml_multiple
222
-
223
- html = ::Asciidoctor.convert(StringIO.new(DOC_MULTI), backend: "html5")
215
+ html = ::Asciidoctor.convert(StringIO.new(DOC_MULTI), backend: 'html5')
224
216
  page = Nokogiri::HTML(html)
225
217
 
226
218
  elements = page.css('img.plantuml')
@@ -228,72 +220,65 @@ class PlantUmlTest < Test::Unit::TestCase
228
220
 
229
221
  elements = page.css('.plantuml-error')
230
222
  assert_equal elements.size, 0
231
-
232
223
  end
233
224
 
234
225
  def test_plantuml_bad_server
235
-
236
226
  Asciidoctor::PlantUml.configure do |c|
237
- c.url = "http://nonexistent.com/plantuml"
227
+ c.url = 'http://nonexistent.com/plantuml'
238
228
  end
239
229
 
240
- html = ::Asciidoctor.convert(StringIO.new(DOC_MULTI), backend: "html5")
230
+ html = ::Asciidoctor.convert(StringIO.new(DOC_MULTI), backend: 'html5')
241
231
  page = Nokogiri::HTML(html)
242
232
 
243
233
  elements = page.css('img.plantuml')
244
- assert_equal elements.size, 3
234
+ assert_equal 3, elements.size
245
235
 
246
236
  elements = page.css('.plantuml-error')
247
- assert_equal elements.size, 0
237
+ assert_equal 0, elements.size
248
238
  end
249
239
 
250
240
  def test_plantuml_invalid_uri
251
-
252
241
  Asciidoctor::PlantUml.configure do |c|
253
- c.url = "ftp://test.com"
242
+ c.url = 'ftp://test.com'
254
243
  end
255
244
 
256
- html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: "html5")
245
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: 'html5')
257
246
  page = Nokogiri::HTML(html)
258
247
  elements = page.css('pre.plantuml-error')
259
248
  assert_equal elements.size, 1
260
249
  end
261
250
 
262
251
  def test_plantuml_nil_uri
263
-
264
252
  Asciidoctor::PlantUml.configure do |c|
265
253
  c.url = nil
266
254
  end
267
255
 
268
- html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: "html5")
256
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: 'html5')
269
257
  page = Nokogiri::HTML(html)
270
258
  elements = page.css('pre.plantuml-error')
271
259
  assert_equal elements.size, 1
272
260
  end
273
261
 
274
262
  def test_plantuml_empty_uri
275
-
276
263
  Asciidoctor::PlantUml.configure do |c|
277
- c.url = ""
264
+ c.url = ''
278
265
  end
279
266
 
280
- html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: "html5")
267
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: 'html5')
281
268
  page = Nokogiri::HTML(html)
282
269
  elements = page.css('pre.plantuml-error')
283
270
  assert_equal elements.size, 1
284
271
  end
285
272
 
286
273
  def test_disable_txt
287
-
288
274
  Asciidoctor::PlantUml.configure do |c|
289
- c.url = "http://localhost:8080/plantuml"
275
+ c.url = 'http://localhost:8080/plantuml'
290
276
  c.txt_enable = false
291
277
  end
292
278
 
293
- html = ::Asciidoctor.convert(StringIO.new(DOC_TXT), backend: "html5")
279
+ html = ::Asciidoctor.convert(StringIO.new(DOC_TXT), backend: 'html5')
294
280
  page = Nokogiri::HTML(html)
295
281
  elements = page.css('pre.plantuml-error')
296
282
  assert_equal elements.size, 1
297
-
298
283
  end
299
284
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-plantuml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Horacio Sanson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-17 00:00:00.000000000 Z
11
+ date: 2019-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +53,19 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '10.5'
41
55
  - !ruby/object:Gem::Dependency
42
- name: nokogiri
56
+ name: rubocop
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '1.6'
61
+ version: '0.66'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '1.6'
68
+ version: '0.66'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: test-unit
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -94,8 +108,8 @@ extensions: []
94
108
  extra_rdoc_files: []
95
109
  files:
96
110
  - lib/asciidoctor-plantuml.rb
97
- - lib/asciidoctor-plantuml/plantuml.rb
98
- - lib/asciidoctor-plantuml/version.rb
111
+ - lib/asciidoctor_plantuml/plantuml.rb
112
+ - lib/asciidoctor_plantuml/version.rb
99
113
  - test/test_plantuml.rb
100
114
  homepage: https://github.com/hsanson/asciidoctor-plantuml
101
115
  licenses:
@@ -109,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
123
  requirements:
110
124
  - - ">="
111
125
  - !ruby/object:Gem::Version
112
- version: '2.1'
126
+ version: '2.3'
113
127
  required_rubygems_version: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -120,6 +134,6 @@ rubyforge_project:
120
134
  rubygems_version: 2.7.6
121
135
  signing_key:
122
136
  specification_version: 4
123
- summary: An extension for Asciidoctor that enables support for PlantUML diagrams.
137
+ summary: Asciidoctor support for PlantUML diagrams.
124
138
  test_files:
125
139
  - test/test_plantuml.rb
@@ -1,286 +0,0 @@
1
- require 'uri'
2
- require 'zlib'
3
- require 'open-uri'
4
- require 'net/http'
5
-
6
- module Asciidoctor
7
- module PlantUml
8
-
9
- class Configuration
10
-
11
- DEFAULT_URL = ENV["PLANTUML_URL"] || ""
12
-
13
- attr_accessor :url, :txt_enable, :svg_enable, :png_enable
14
-
15
- def initialize
16
- @url = DEFAULT_URL
17
- @txt_enable = true
18
- @svg_enable = true
19
- @png_enable = true
20
- end
21
- end
22
-
23
- class << self
24
- attr_writer :configuration
25
- end
26
-
27
- def self.configuration
28
- @configuration ||= Configuration.new
29
- end
30
-
31
- def self.configure
32
- yield(configuration)
33
- end
34
-
35
- class Processor
36
-
37
- FORMATS = ["png", "svg", "txt"]
38
- DEFAULT_FORMAT = FORMATS[0]
39
-
40
- class << self
41
- def valid_format?(format)
42
- FORMATS.include?(format)
43
- end
44
-
45
- def server_url
46
- PlantUml::configuration.url
47
- end
48
-
49
- def txt_enabled?
50
- PlantUml::configuration.txt_enable
51
- end
52
-
53
- def png_enabled?
54
- PlantUml::configuration.png_enable
55
- end
56
-
57
- def svg_enabled?
58
- PlantUml::configuration.svg_enable
59
- end
60
-
61
- def enabled?
62
- txt_enabled? || png_enabled? || svg_enabled?
63
- end
64
-
65
- def plantuml_content(code, attrs = {})
66
-
67
- format = attrs["format"] || DEFAULT_FORMAT
68
-
69
- if !enabled?
70
- return plantuml_disabled_content(code, attrs)
71
- end
72
-
73
- if !valid_uri?(server_url)
74
- return plantuml_server_unavailable_content(server_url, attrs)
75
- end
76
-
77
- case format
78
- when "png"
79
- plantuml_img_content(code, format, attrs)
80
- when "txt"
81
- if txt_enabled?
82
- plantuml_txt_content(code, format, attrs)
83
- else
84
- plantuml_invalid_content(format, attrs)
85
- end
86
- when "svg"
87
- plantuml_img_content(code, format, attrs)
88
- else
89
- plantuml_invalid_content(format, attrs)
90
- end
91
- end
92
-
93
- # Compression code used to generate PlantUML URLs. Taken directly from the
94
- # Transcoder class in the PlantUML java code.
95
- def gen_url(text, format)
96
- result = ""
97
- compressedData = Zlib::Deflate.deflate(text)
98
- compressedData.chars.each_slice(3) do |bytes|
99
- #print bytes[0], ' ' , bytes[1] , ' ' , bytes[2]
100
- b1 = bytes[0].nil? ? 0 : (bytes[0].ord & 0xFF)
101
- b2 = bytes[1].nil? ? 0 : (bytes[1].ord & 0xFF)
102
- b3 = bytes[2].nil? ? 0 : (bytes[2].ord & 0xFF)
103
- result += append3bytes(b1, b2, b3)
104
- end
105
- join_paths(server_url, "/#{format}/", result).to_s
106
- end
107
-
108
- private
109
-
110
- def plantuml_txt_content(code, format, attrs = {})
111
- begin
112
- url = gen_url(code, format)
113
- open(url) do |f|
114
- plantuml_ascii_content(f.read, format, attrs)
115
- end
116
- rescue
117
- plantuml_img_content(code, format, attrs)
118
- end
119
- end
120
-
121
- def plantuml_ascii_content(code, format, attrs = {})
122
- content = "<div class=\"listingblock\">"
123
- content += "<div class=\"content\">"
124
- content += "<pre "
125
- content +="id=\"#{attrs['id']}\" " if attrs['id']
126
- content +="class=\"plantuml\">\n"
127
- content += code
128
- content +="</pre>"
129
- content += "</div>"
130
- content += "</div>"
131
- end
132
-
133
- def plantuml_img_content(code, format, attrs = {})
134
- content = "<div class=\"imageblock\">"
135
- content += "<div class=\"content\">"
136
- content += "<img "
137
- content +="id=\"#{attrs['id']}\" " if attrs['id']
138
- content +="class=\"plantuml\" "
139
- content +="width=\"#{attrs['width']}\" " if attrs['width']
140
- content +="height=\"#{attrs['height']}\" " if attrs['height']
141
- content +="alt=\"#{attrs['alt']}\" " if attrs['alt']
142
- content +="src=\"#{gen_url(code, format)}\" />"
143
- content += "</div>"
144
- content += "</div>"
145
- end
146
-
147
- def plantuml_invalid_content(format, attrs = {})
148
- content = "<div class=\"listingblock\">"
149
- content += "<div class=\"content\">"
150
- content += "<pre "
151
- content +="id=\"#{attrs['id']}\" " if attrs['id']
152
- content +="class=\"plantuml plantuml-error\"> "
153
- content += "PlantUML Error: Invalid format \"#{format}\""
154
- content +="</pre>"
155
- content += "</div>"
156
- content += "</div>"
157
- end
158
-
159
- def plantuml_server_unavailable_content(url, attrs = {})
160
- content = "<div class=\"listingblock\">"
161
- content += "<div class=\"content\">"
162
- content += "<pre "
163
- content +="id=\"#{attrs['id']}\" " if attrs['id']
164
- content +="class=\"plantuml plantuml-error\"> "
165
- content += "PlantUML Error: cannot connect to PlantUML server at \"#{url}\""
166
- content +="</pre>"
167
- content += "</div>"
168
- content += "</div>"
169
- end
170
-
171
- def plantuml_disabled_content(code, attrs = {})
172
- content = "<div class=\"listingblock\">"
173
- content += "<div class=\"content\">"
174
- content += "<pre "
175
- content +="id=\"#{attrs['id']}\" " if attrs['id']
176
- content +="class=\"plantuml plantuml-error\">\n"
177
- content += code
178
- content +="</pre>"
179
- content += "</div>"
180
- content += "</div>"
181
- end
182
-
183
- def encode6bit(b)
184
- if b < 10
185
- return ('0'.ord + b).chr
186
- end
187
- b = b - 10
188
- if b < 26
189
- return ('A'.ord + b).chr
190
- end
191
- b = b - 26
192
- if b < 26
193
- return ('a'.ord + b).chr
194
- end
195
- b = b - 26
196
- if b == 0
197
- return '-'
198
- end
199
- if b == 1
200
- return '_'
201
- end
202
- return '?'
203
- end
204
-
205
- def append3bytes(b1, b2, b3)
206
- c1 = b1 >> 2
207
- c2 = ((b1 & 0x3) << 4) | (b2 >> 4)
208
- c3 = ((b2 & 0xF) << 2) | (b3 >> 6)
209
- c4 = b3 & 0x3F
210
- return encode6bit(c1 & 0x3F).chr +
211
- encode6bit(c2 & 0x3F).chr +
212
- encode6bit(c3 & 0x3F).chr +
213
- encode6bit(c4 & 0x3F).chr
214
- end
215
-
216
- # Make a call to the PlantUML server with the simplest diagram possible to
217
- # check if the server is available or not.
218
- def check_server(check_url)
219
- response = Net::HTTP.get_response(URI(check_url))
220
- return response.is_a?(Net::HTTPSuccess)
221
- rescue
222
- return false
223
- end
224
-
225
- def valid_uri?(uri)
226
- !(uri =~ /\A#{URI::regexp(['http', 'https'])}\z/).nil?
227
- end
228
-
229
- def join_paths(*paths, separator: '/')
230
- paths = paths.compact.reject(&:empty?)
231
- last = paths.length - 1
232
- paths.each_with_index.map { |path, index|
233
- expand_path(path, index, last, separator)
234
- }.join
235
- end
236
-
237
- def expand_path(path, current, last, separator)
238
- if path.start_with?(separator) && current != 0
239
- path = path[1..-1]
240
- end
241
-
242
- unless path.end_with?(separator) || current == last
243
- path = [path, separator]
244
- end
245
-
246
- path
247
- end
248
- end
249
- end
250
-
251
- class BlockProcessor < Asciidoctor::Extensions::BlockProcessor
252
-
253
- use_dsl
254
- named :plantuml
255
- on_context :listing
256
- content_model :simple
257
-
258
- def process(parent, target, attrs)
259
-
260
- lines = target.lines
261
-
262
- if !(target.lines[0] =~ /@startuml/)
263
- lines = ["@startuml"] + target.lines
264
- end
265
-
266
- if !(target.lines[-1] =~ /@enduml/)
267
- lines += ["@enduml"]
268
- end
269
-
270
- content = Processor.plantuml_content(lines.join("\n"), attrs)
271
-
272
- return create_plantuml_block(parent, content, attrs)
273
-
274
- end
275
-
276
- private
277
-
278
- def create_plantuml_block(parent, content, attrs)
279
- Asciidoctor::Block.new parent, :pass, { content_model: :raw,
280
- source: content, subs: :default }.merge(attrs)
281
- end
282
-
283
- end
284
-
285
- end
286
- end
@@ -1,5 +0,0 @@
1
- module Asciidoctor
2
- module PlantUML
3
- VERSION = '0.0.9'.freeze
4
- end
5
- end