asciidoctor-plantuml 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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