asciidoctor-plantuml 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed5ecef9a1e029694a9d18e2800a7a95869455e6
4
+ data.tar.gz: b47a156f1e832ac35092f3ff6dfec092ebda99a6
5
+ SHA512:
6
+ metadata.gz: 4b8ee673ee3d5a3432a27d94bee9525e7e941791f6055a529300a5a065a1d659925d7d63b8a5d942e35ec4ec6ca11d2a5387232c9fb2cd2e28988b0500850742
7
+ data.tar.gz: 34a6ebd97cacd0ee47361c6ba1e62aa014f6e4ba028f0e7a43863a51212ae2985be179db107db811daf3094097453189d77938d3d65f3e5eac0ad5ba3f86cb22
@@ -0,0 +1,7 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/extensions'
3
+ require_relative 'asciidoctor-plantuml/plantuml'
4
+
5
+ Asciidoctor::Extensions.register do
6
+ block Asciidoctor::PlantUml::BlockProcessor, :plantuml
7
+ end
@@ -0,0 +1,178 @@
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"] || "http://localhost:8080/plantuml"
12
+
13
+ attr_accessor :url, :test
14
+
15
+ def initialize
16
+ @url = DEFAULT_URL
17
+ @test = false
18
+ end
19
+ end
20
+
21
+ class << self
22
+ attr_writer :configuration
23
+ end
24
+
25
+ def self.configuration
26
+ @configuration ||= Configuration.new
27
+ end
28
+
29
+ def self.configure
30
+ yield(configuration)
31
+ end
32
+
33
+ module Processor
34
+
35
+ FORMATS = ["png", "svg", "txt"]
36
+ DEFAULT_FORMAT = FORMATS[0]
37
+
38
+ def valid_format?(format)
39
+ FORMATS.include?(format)
40
+ end
41
+
42
+ def server_url
43
+ PlantUml::configuration.url
44
+ end
45
+
46
+ def plantuml_content(code, format, attrs = {})
47
+ content = "<img "
48
+ content +="id=\"#{attrs['id']}\" " if attrs['id']
49
+ content +="class=\"plantuml\" "
50
+ content +="width=\"#{attrs['width']}\" " if attrs['width']
51
+ content +="height=\"#{attrs['height']}\" " if attrs['height']
52
+ content +="alt=\"#{attrs['alt']}\" " if attrs['alt']
53
+ content +="src=\"#{gen_url(code, format)}\" />"
54
+ end
55
+
56
+ # Compression code used to generate PlantUML URLs. Taken directly from the
57
+ # Transcoder class in the PlantUML java code.
58
+ def gen_url(text, format)
59
+ result = ""
60
+ compressedData = Zlib::Deflate.deflate(text)
61
+ compressedData.chars.each_slice(3) do |bytes|
62
+ #print bytes[0], ' ' , bytes[1] , ' ' , bytes[2]
63
+ b1 = bytes[0].nil? ? 0 : (bytes[0].ord & 0xFF)
64
+ b2 = bytes[1].nil? ? 0 : (bytes[1].ord & 0xFF)
65
+ b3 = bytes[2].nil? ? 0 : (bytes[2].ord & 0xFF)
66
+ result += append3bytes(b1, b2, b3)
67
+ end
68
+ join_paths(server_url, "/#{format}/", result).to_s
69
+ end
70
+
71
+ def encode6bit(b)
72
+ if b < 10
73
+ return ('0'.ord + b).chr
74
+ end
75
+ b = b - 10
76
+ if b < 26
77
+ return ('A'.ord + b).chr
78
+ end
79
+ b = b - 26
80
+ if b < 26
81
+ return ('a'.ord + b).chr
82
+ end
83
+ b = b - 26
84
+ if b == 0
85
+ return '-'
86
+ end
87
+ if b == 1
88
+ return '_'
89
+ end
90
+ return '?'
91
+ end
92
+
93
+ def append3bytes(b1, b2, b3)
94
+ c1 = b1 >> 2
95
+ c2 = ((b1 & 0x3) << 4) | (b2 >> 4)
96
+ c3 = ((b2 & 0xF) << 2) | (b3 >> 6)
97
+ c4 = b3 & 0x3F
98
+ return encode6bit(c1 & 0x3F).chr +
99
+ encode6bit(c2 & 0x3F).chr +
100
+ encode6bit(c3 & 0x3F).chr +
101
+ encode6bit(c4 & 0x3F).chr
102
+ end
103
+
104
+ # Make a call to the PlantUML server with the simplest diagram possible to
105
+ # check if the server is available or not.
106
+ def check_server(check_url)
107
+ response = Net::HTTP.get_response(URI(check_url))
108
+ return response.is_a?(Net::HTTPSuccess)
109
+ rescue
110
+ return false
111
+ end
112
+
113
+
114
+ def create_plantuml_block(parent, content)
115
+ Asciidoctor::Block.new parent, :pass, :content_model => :raw,
116
+ :source => content, :subs => :default
117
+ end
118
+
119
+ def join_paths(*paths, separator: '/')
120
+ paths = paths.compact.reject(&:empty?)
121
+ last = paths.length - 1
122
+ paths.each_with_index.map { |path, index|
123
+ expand_path(path, index, last, separator)
124
+ }.join
125
+ end
126
+
127
+ def expand_path(path, current, last, separator)
128
+ if path.start_with?(separator) && current != 0
129
+ path = path[1..-1]
130
+ end
131
+
132
+ unless path.end_with?(separator) || current == last
133
+ path = [path, separator]
134
+ end
135
+
136
+ path
137
+ end
138
+ end
139
+
140
+ class BlockProcessor < Asciidoctor::Extensions::BlockProcessor
141
+ include Processor
142
+
143
+ def process(parent, target, attrs)
144
+
145
+ testing = attrs["test"] == "true"
146
+
147
+ check_url = join_paths(server_url, "/png/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000")
148
+
149
+ if ! check_server(check_url) && ! testing
150
+ content = "<div class='plantuml'>PlantUML server [#{check_url}] is unreachable</div>"
151
+ return create_plantuml_block(parent, content)
152
+ end
153
+
154
+ format = attrs["format"] || DEFAULT_FORMAT
155
+
156
+ if ! valid_format?(format)
157
+ content = "<div class='plantuml'>Invalid format #{format}</div>"
158
+ return create_plantuml_block(parent, content)
159
+ end
160
+
161
+ lines = target.lines
162
+
163
+ if !(target.lines[0] =~ /@startuml/)
164
+ lines = ["@startuml"] + target.lines
165
+ end
166
+
167
+ if !(target.lines[-1] =~ /@enduml/)
168
+ lines += ["@enduml"]
169
+ end
170
+
171
+ content = plantuml_content(lines.join("\n"), format, attrs)
172
+ return create_plantuml_block(parent, content)
173
+
174
+ end
175
+ end
176
+
177
+ end
178
+ end
@@ -0,0 +1,5 @@
1
+ module Asciidoctor
2
+ module PlantUML
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,166 @@
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", test="true"]
11
+ User -> (Start)
12
+ User --> (Use the application) : Label
13
+ eos
14
+
15
+ DOC_BASIC2 = <<-eos
16
+ = Hello PlantUML!
17
+
18
+ [plantuml, format="png", test="true"]
19
+ @startuml
20
+ User -> (Start)
21
+ User --> (Use the application) : Label
22
+ @enduml
23
+ eos
24
+
25
+ DOC_ID = <<-eos
26
+ = Hello PlantUML!
27
+
28
+ [plantuml, format="png", test="true", id="myId"]
29
+ User -> (Start)
30
+ User --> (Use the application) : Label
31
+ eos
32
+
33
+ DOC_DIM = <<-eos
34
+ = Hello PlantUML!
35
+
36
+ [plantuml, format="png", test="true", width="100px", height="50px"]
37
+ User -> (Start)
38
+ User --> (Use the application) : Label
39
+ eos
40
+
41
+ DOC_ALT = <<-eos
42
+ = Hello PlantUML!
43
+
44
+ [plantuml, format="png", test="true", alt="alt"]
45
+ User -> (Start)
46
+ User --> (Use the application) : Label
47
+ eos
48
+
49
+ DOC_BAD_FORMAT = <<-eos
50
+ = Hello PlantUML!
51
+
52
+ [plantuml, format="jpg", test="true"]
53
+ User -> (Start)
54
+ User --> (Use the application) : Label
55
+ eos
56
+
57
+ DOC_MULTI = <<-eos
58
+ = Hello PlantUML!
59
+
60
+ [plantuml, format="png", test="true"]
61
+ User -> (Start)
62
+ User --> (Use the application) : Label
63
+
64
+ [plantuml, format="txt", test="true"]
65
+ User -> (Start)
66
+ User --> (Use the application) : Label
67
+ eos
68
+
69
+ class PlantUmlTest < Test::Unit::TestCase
70
+
71
+ GENURL = "http://localhost:8080/plantuml/png/U9npA2v9B2efpStX2YrEBLBGjLFG20Q9Q4Bv804WIw4a8rKXiQ0W9pCviIGpFqzJmKh19p4fDOVB8JKl1QWT05kd5wq0"
72
+
73
+ def test_plantuml_block_processor
74
+
75
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC), backend: "html5")
76
+ page = Nokogiri::HTML(html)
77
+
78
+ elements = page.css('img.plantuml')
79
+
80
+ assert_equal elements.size, 1
81
+
82
+ element = elements.first
83
+
84
+ assert_equal GENURL, element["src"]
85
+ end
86
+
87
+ def test_plantuml_block_processor2
88
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BASIC2), backend: "html5")
89
+ page = Nokogiri::HTML(html)
90
+
91
+ elements = page.css('img.plantuml')
92
+
93
+ assert_equal elements.size, 1
94
+
95
+ element = elements.first
96
+
97
+ assert_equal GENURL, element["src"]
98
+ end
99
+
100
+ def test_plantuml_id_attribute
101
+
102
+ html = ::Asciidoctor.convert(StringIO.new(DOC_ID), backend: "html5")
103
+ page = Nokogiri::HTML(html)
104
+
105
+ elements = page.css('img.plantuml')
106
+
107
+ assert_equal elements.size, 1
108
+ element = elements.first
109
+
110
+ assert_equal "myId", element["id"]
111
+
112
+ end
113
+
114
+ def test_plantuml_dimension_attribute
115
+
116
+ html = ::Asciidoctor.convert(StringIO.new(DOC_DIM), backend: "html5")
117
+ page = Nokogiri::HTML(html)
118
+
119
+ elements = page.css('img.plantuml')
120
+
121
+ assert_equal elements.size, 1
122
+ element = elements.first
123
+
124
+ assert_equal "100px", element["width"]
125
+ assert_equal "50px", element["height"]
126
+
127
+ end
128
+
129
+ def test_plantuml_alt_attribute
130
+
131
+ html = ::Asciidoctor.convert(StringIO.new(DOC_ALT), backend: "html5")
132
+ page = Nokogiri::HTML(html)
133
+
134
+ elements = page.css('img.plantuml')
135
+
136
+ assert_equal elements.size, 1
137
+ element = elements.first
138
+
139
+ assert_equal "alt", element["alt"]
140
+
141
+ end
142
+
143
+ def test_should_show_bad_format
144
+ html = ::Asciidoctor.convert(StringIO.new(DOC_BAD_FORMAT), backend: "html5")
145
+
146
+ page = Nokogiri::HTML(html)
147
+
148
+ elements = page.css('img.plantuml')
149
+ assert_equal elements.size, 0
150
+
151
+ elements = page.css('div.plantuml')
152
+ assert_equal elements.size, 1
153
+ end
154
+
155
+ def test_plantuml_multiple
156
+
157
+ html = ::Asciidoctor.convert(StringIO.new(DOC_MULTI), backend: "html5")
158
+ page = Nokogiri::HTML(html)
159
+
160
+ elements = page.css('img.plantuml')
161
+
162
+ assert_equal elements.size, 2
163
+
164
+ end
165
+
166
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asciidoctor-plantuml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Horacio Sanson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: asciidoctor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
69
+ description: Asciidoctor PlantUML extension
70
+ email:
71
+ - hsanson@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - lib/asciidoctor-plantuml.rb
77
+ - lib/asciidoctor-plantuml/plantuml.rb
78
+ - lib/asciidoctor-plantuml/version.rb
79
+ - test/test_plantuml.rb
80
+ homepage: https://github.com/hsanson/asciidoctor-plantuml
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.5.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: An extension for Asciidoctor that enables support for PlantUML diagrams.
104
+ test_files:
105
+ - test/test_plantuml.rb