jekyll-kroki 0.5.0 → 1.0.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: 39c2c3f9463c5788864d00c4ed80e9aa826a1aa1d1380dbff2be92407958f0e5
4
- data.tar.gz: 38340a5a1deaa705a0b7cde596e5eb007da3d84526b2641e9cad6e9f38e86809
3
+ metadata.gz: 7b092bf9850f67c8e4bd7bd0d454aeeaa274b372f5ae8976f6fb05cab3f8372a
4
+ data.tar.gz: 1c8b189b173440b3694156281c41915c204d55b0d35d46bc866a51b0287ea73e
5
5
  SHA512:
6
- metadata.gz: dbedea8bbf380c047c91cee38bc7fade0c9a6a0e3aa8735b7a18e3361219cb796fb3b89b17583db402f0b03bf083f13892d53a7677cc904d12f6be6990bfee98
7
- data.tar.gz: 6c3cf11ca513c6b16331547bcd69003b77dd62c3a09b46c52e440684a5001f8c47318962037faa3a0bce5cf1e99c2dfe4a2f5f4e00f4bc0eb893ef0fb174efa6
6
+ metadata.gz: bc181d7f3288979cb09d8aeae9f915de5099ecbe2b0d6b3c56f941935e3d7ea264051b7fa1c0c850f476930613bb45a2723f623f3b97867b65283e752466f16a
7
+ data.tar.gz: 9e46a87b36b24fc80e2a9349044b87c9c0251f59a8b1060ac498b00bf7a012dbf70415be23752988684ba234de27865526db15ea7552a764d6b4953e5fd7f975
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Ruby",
3
- "image": "mcr.microsoft.com/devcontainers/ruby:3.4-bullseye",
3
+ "image": "mcr.microsoft.com/devcontainers/ruby:4.0-bookworm",
4
4
  "customizations": {
5
5
  "vscode": {
6
6
  "extensions": [
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ plugins:
5
5
 
6
6
  AllCops:
7
7
  NewCops: enable
8
- TargetRubyVersion: 2.7
8
+ TargetRubyVersion: 3.0
9
9
 
10
10
  Gemspec/DevelopmentDependencies:
11
11
  EnforcedStyle: gemspec
@@ -3,5 +3,9 @@
3
3
  "editor.rulers": [
4
4
  120
5
5
  ],
6
- "rubyLsp.formatter": "rubocop"
6
+ "rubyLsp.formatter": "rubocop",
7
+ "cSpell.language": "en-GB",
8
+ "cSpell.words": [
9
+ "Kroki"
10
+ ]
7
11
  }
data/README.md CHANGED
@@ -2,9 +2,11 @@
2
2
  [![Gem Version](https://badge.fury.io/rb/jekyll-kroki.svg)](https://badge.fury.io/rb/jekyll-kroki)
3
3
 
4
4
  # jekyll-kroki
5
+
5
6
  A [Jekyll](https://jekyllrb.com/) plugin to convert diagram descriptions into images using [Kroki](https://kroki.io/).
6
7
 
7
8
  ## Installation
9
+
8
10
  Add the `jekyll-kroki` Gem to the `:jekyll_plugins` group of your site's Gemfile:
9
11
 
10
12
  ```ruby
@@ -14,6 +16,7 @@ end
14
16
  ```
15
17
 
16
18
  ## Usage
19
+
17
20
  Kroki supports over 25 popular diagram scripting languages, including Blockdiag, D2, GraphViz, Mermaid, and PlantUML. The [examples](https://kroki.io/examples.html) page and complete list of [supported diagram languages](https://kroki.io/#support) provide a taste of what's possible.
18
21
 
19
22
  In Markdown, simply write your diagram descriptions inside a fenced code block with the language specified:
@@ -28,27 +31,32 @@ Kroki --> Jekyll: Rendered diagram in SVG format
28
31
  ```
29
32
  ````
30
33
 
31
- When Jekyll builds your site, the `jekyll-kroki` plugin will encode the diagrams, send them to the Kroki server for rendering, then replace the diagram descriptions in the generated HTML with the rendered images in SVG format:
34
+ When Jekyll builds your site, the `jekyll-kroki` plugin encodes the diagram descriptions, renders them as SVG images using the Kroki server, then embeds them in the generated HTML:
32
35
 
33
36
  ![sample-diagram](https://github.com/felixvanoost/jekyll-kroki/assets/10233016/244d2ec4-b09b-4a5f-8164-3851574c3dd2)
34
37
 
35
- The site remains fully static as the images are directly embedded in the HTML files served by Jekyll. Jekyll only depends on the Kroki server - which can also be run locally - during the build stage, and all of the client-side processing that is normally used to render diagrams into images is eliminated.
38
+ Since the images are rendered and embedded at build-time, the Jekyll site remains completely static and doesn't depend on access to the Kroki server later on. This also eliminates all of the client-side processing that is typically used to render diagrams into images.
36
39
 
37
40
  ### Advantages
38
41
 
39
42
  #### Consistent syntax
43
+
40
44
  Instead of using Liquid tags, `jekyll-kroki` leverages the same Markdown fenced code block syntax used by both [GitLab](https://docs.gitlab.com/ee/user/markdown.html#diagrams-and-flowcharts) and [GitHub](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-diagrams) to display diagrams. Besides being more consistent, this means that diagram descriptions in Markdown files can be displayed consistently as images across the GitLab/GitHub UI and on GitLab/GitHub Pages sites generated using Jekyll. GitLab currently supports Mermaid and PlantUML, while GitHub only supports Mermaid.
41
45
 
42
46
  #### Seamless GitLab integration
43
- Self-managed GitLab instances can additionally enable the [Kroki integration](https://docs.gitlab.com/ee/administration/integration/kroki.html), which adds support for all the same diagram scripting languages used by `jekyll-kroki`. Furthermore, by pointing both GitLab and `jekyll-kroki` to the same Kroki instance, you can guarantee that diagrams are generated using identical versions of the diagram libraries.
47
+
48
+ Self-managed or dedicated GitLab instances can additionally enable the [Kroki integration](https://docs.gitlab.com/ee/administration/integration/kroki.html), which adds support for all the diagram scripting languages used by `jekyll-kroki`. Furthermore, by pointing both GitLab and `jekyll-kroki` to the same Kroki instance, you can guarantee that diagrams are generated using identical versions of the diagram libraries.
44
49
 
45
50
  #### Speed
46
- The server-side nature of Kroki means that you don't have to deal with installing or updating any diagram library dependencies on your machine. Jekyll sites that are generated in CI/CD pipelines will thus build faster.
51
+
52
+ The server-side nature of Kroki means that you don't have to deal with installing or updating any diagram library dependencies on your machine. Jekyll sites that are generated in CI/CD pipelines can bypass these setup steps and will thus build faster. `jekyll-kroki` is built with performance in mind to minimise the build time of even the largest sites with thousands of diagrams.
47
53
 
48
54
  #### Flexibility
49
- Kroki is available either as a free service or self-hosted using Docker. Organisations that frequently build large Jekyll sites with many diagrams or want maximum control over their data have the option of running their own Kroki instance to provide consistency and use compute resources efficiently.
55
+
56
+ Kroki is available either as a free service or self-hosted using Docker. Organisations that frequently build large Jekyll sites with many diagrams or want maximum control over their data can choose to operate their own Kroki instance to ensure consistency and use compute resources efficiently. For individuals, you can also opt to run Kroki locally.
50
57
 
51
58
  ### Configuration
59
+
52
60
  You can specify the following parameters in the Jekyll `_config.yml` file:
53
61
 
54
62
  | Parameter | Default value | Description |
@@ -69,7 +77,8 @@ kroki:
69
77
  ```
70
78
 
71
79
  ### Security
72
- Embedding diagrams as SVGs directly within HTML files can be dangerous. You should only use a Kroki instance that you trust (or run your own!). For additional security, you can configure a [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) using custom Webrick headers in the Jekyll `_config.yml` file:
80
+
81
+ Embedding untrusted SVGs directly in HTML files can introduce security risks. Use a Kroki instance that you trust, or consider hosting your own local/private instance. For added security, you can configure a [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) by adding custom Webrick headers in your Jekyll `_config.yml` file:
73
82
 
74
83
  ```yaml
75
84
  webrick:
@@ -78,4 +87,5 @@ webrick:
78
87
  ```
79
88
 
80
89
  ## Contributing
90
+
81
91
  Bug reports and pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class Kroki
5
+ # Reads, validates, and exposes the jekyll-kroki configuration from the Jekyll site config.
6
+ class Config
7
+ DEFAULT_KROKI_URL = "https://kroki.io"
8
+ DEFAULT_HTTP_RETRIES = 3
9
+ DEFAULT_HTTP_TIMEOUT = 15
10
+ DEFAULT_MAX_CONCURRENT_DOCS = 8
11
+
12
+ attr_reader :kroki_url, :http_retries, :http_timeout, :max_concurrent_docs
13
+
14
+ # @param [Hash] The Jekyll site configuration.
15
+ # @raise [TypeError] If any parameter has an incorrect type.
16
+ # @raise [ArgumentError] If any parameter is out of the valid range.
17
+ def initialize(site_config)
18
+ kroki_config = site_config.fetch("kroki", {})
19
+
20
+ @kroki_url = parse_url(kroki_config)
21
+ @http_retries = parse_integer(kroki_config, "http_retries", DEFAULT_HTTP_RETRIES, min: 0)
22
+ @http_timeout = parse_integer(kroki_config, "http_timeout", DEFAULT_HTTP_TIMEOUT, min: 0)
23
+ @max_concurrent_docs = parse_integer(kroki_config, "max_concurrent_docs", DEFAULT_MAX_CONCURRENT_DOCS, min: 1)
24
+
25
+ freeze
26
+ end
27
+
28
+ private
29
+
30
+ def parse_url(kroki_config)
31
+ param_name = "url"
32
+ raw = kroki_config.fetch(param_name, DEFAULT_KROKI_URL)
33
+ uri = URI.parse(raw)
34
+ raise TypeError, "'#{param_name}' is not a valid HTTP URL" unless uri.is_a?(URI::HTTP)
35
+
36
+ uri
37
+ end
38
+
39
+ def parse_integer(kroki_config, param_name, default, min:)
40
+ value = kroki_config.fetch(param_name, default)
41
+ raise TypeError, "'#{param_name}' must be an integer" unless value.is_a?(Integer)
42
+ raise ArgumentError, "'#{param_name}' must be >= #{min}" if value < min
43
+
44
+ value
45
+ end
46
+ end
47
+ end
48
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  class Kroki
5
- VERSION = "0.5.0"
5
+ VERSION = "1.0.0"
6
6
  end
7
7
  end
data/lib/jekyll/kroki.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "kroki/config"
3
4
  require_relative "kroki/version"
4
5
 
5
6
  require "async"
6
7
  require "async/semaphore"
7
8
  require "base64"
9
+ require "concurrent-ruby"
10
+ require "digest"
8
11
  require "faraday"
9
12
  require "faraday/retry"
10
13
  require "httpx/adapters/faraday"
@@ -15,130 +18,117 @@ require "zlib"
15
18
  module Jekyll
16
19
  # Converts diagram descriptions into images using Kroki.
17
20
  class Kroki
18
- DEFAULT_KROKI_URL = "https://kroki.io"
19
- DEFAULT_HTTP_RETRIES = 3
20
- DEFAULT_HTTP_TIMEOUT = 15
21
- DEFAULT_MAX_CONCURRENT_DOCS = 8
21
+ SUPPORTED_LANGUAGES = %w[actdiag blockdiag bpmn bytefield c4plantuml d2 dbml diagramsnet ditaa erd excalidraw
22
+ graphviz mermaid nomnoml nwdiag packetdiag pikchr plantuml rackdiag seqdiag structurizr
23
+ svgbob symbolator tikz umlet vega vegalite wavedrom wireviz].freeze
22
24
  EXPECTED_HTML_TAGS = %w[code div].freeze
25
+ DIAGRAM_SELECTOR = SUPPORTED_LANGUAGES.flat_map do |language|
26
+ EXPECTED_HTML_TAGS.map { |tag| "#{tag}[class~='language-#{language}']" }
27
+ end.join(", ").freeze
28
+
23
29
  HTTP_RETRY_INTERVAL_BACKOFF_FACTOR = 2
24
30
  HTTP_RETRY_INTERVAL_RANDOMNESS = 0.5
25
31
  HTTP_RETRY_INTERVAL = 0.1
26
- SUPPORTED_LANGUAGES = %w[actdiag blockdiag bpmn bytefield c4plantuml d2 dbml diagramsnet ditaa erd excalidraw
27
- graphviz mermaid nomnoml nwdiag packetdiag pikchr plantuml rackdiag seqdiag structurizr
28
- svgbob symbolator tikz umlet vega vegalite wavedrom wireviz].freeze
32
+
33
+ @diagram_cache = Concurrent::Map.new
29
34
 
30
35
  class << self
31
36
  # Renders and embeds all diagram descriptions in the given Jekyll site using Kroki.
32
37
  #
33
38
  # @param [Jekyll::Site] The Jekyll site to embed diagrams in.
34
39
  def embed_site(site)
35
- kroki_url = get_kroki_url(site.config)
36
- http_retries = get_http_retries(site.config)
37
- http_timeout = get_http_timeout(site.config)
38
- connection = setup_connection(kroki_url, http_retries, http_timeout)
39
-
40
- max_concurrent_docs = get_max_concurrent_docs(site.config)
41
- rendered_diag = embed_docs_in_site(site, connection, max_concurrent_docs)
42
- unless rendered_diag.zero?
43
- puts "[jekyll-kroki] Rendered #{rendered_diag} diagrams using Kroki instance at '#{kroki_url}'"
44
- end
45
- rescue StandardError => e
46
- exit(e)
40
+ config = Config.new(site.config)
41
+ connection = setup_connection(config.kroki_url, config.http_retries, config.http_timeout)
42
+
43
+ rendered_diag = embed_docs_in_site(site, connection, config.max_concurrent_docs)
44
+ return unless rendered_diag.positive?
45
+
46
+ Jekyll.logger.info(
47
+ "[jekyll-kroki] Rendered #{rendered_diag} diagrams using Kroki instance at '#{config.kroki_url}'"
48
+ )
47
49
  end
48
50
 
49
51
  # Renders the diagram descriptions in all Jekyll pages and documents in the given Jekyll site. Pages / documents
50
- # are rendered concurrently up to the limit defined by DEFAULT_MAX_CONCURRENT_DOCS.
52
+ # are rendered concurrently up to the limit defined by max_concurrent_docs.
51
53
  #
52
54
  # @param [Jekyll::Site] The Jekyll site to embed diagrams in.
53
55
  # @param [Faraday::Connection] The Faraday connection to use.
54
56
  # @param [Integer] The maximum number of documents to render concurrently.
55
57
  # @return [Integer] The number of successfully rendered diagrams.
56
58
  def embed_docs_in_site(site, connection, max_concurrent_docs)
57
- rendered_diag = 0
58
59
  semaphore = Async::Semaphore.new(max_concurrent_docs)
59
60
 
60
- Async do |task|
61
- tasks = (site.pages + site.documents).filter_map do |doc|
61
+ Async do
62
+ (site.pages + site.documents).filter_map do |doc|
62
63
  next unless embeddable?(doc)
63
64
 
64
- async_embed_single_doc(task, semaphore, connection, doc)
65
- end
66
-
67
- rendered_diag = tasks.sum(&:wait)
68
- end
69
-
70
- rendered_diag
71
- end
72
-
73
- # Renders the supported diagram descriptions in a single document asynchronously, respecting the concurrency limit
74
- # imposed by the provided semaphore.
75
- #
76
- # @param [Async::Task] The parent async task to spawn a child task from.
77
- # @param [Async::Semaphore] A semaphore to limit concurrency.
78
- # @param [Faraday::Connection] The Faraday connection to use.
79
- # @param [Jekyll::Page, Jekyll::Document] The document to process.
80
- # @return [Integer] The number of successfully rendered diagrams.
81
- def async_embed_single_doc(task, semaphore, connection, doc)
82
- task.async do
83
- semaphore.async { embed_single_doc(connection, doc) }.wait
84
- rescue StandardError => e
85
- warn "[jekyll-kroki] Error rendering diagram: #{e.message}".red
86
- 0
87
- end
65
+ semaphore.async do
66
+ embed_single_doc(connection, doc)
67
+ rescue StandardError => e
68
+ Jekyll.logger.error "[jekyll-kroki] Failed to render diagram in '#{doc.relative_path}': #{e.message}"
69
+ 0
70
+ end
71
+ end.sum(&:wait)
72
+ end.wait
88
73
  end
89
74
 
90
- # Renders the supported diagram descriptions in a single document and embeds them as inline SVGs in the HTML
91
- # source.
75
+ # Renders the supported diagram descriptions in a single document sequentially and embeds them as inline SVGs in
76
+ # the HTML source. Returns without modifying the document if no supported diagram descriptions are found.
92
77
  #
93
78
  # @param [Faraday::Connection] The Faraday connection to use.
94
79
  # @param [Jekyll::Page, Jekyll::Document] The document to process.
95
80
  # @return [Integer] The number of successfully rendered diagrams.
96
81
  def embed_single_doc(connection, doc)
97
- # Parse the HTML document.
98
82
  parsed_doc = Nokogiri::HTML(doc.output)
83
+ nodes = parsed_doc.css(DIAGRAM_SELECTOR)
84
+ return 0 if nodes.empty?
99
85
 
100
- rendered_diag = 0
101
- SUPPORTED_LANGUAGES.each do |language|
102
- EXPECTED_HTML_TAGS.each do |tag|
103
- parsed_doc.css("#{tag}[class~='language-#{language}']").each do |diagram_desc|
104
- # Replace the diagram description with the SVG representation rendered by Kroki.
105
- diagram_desc.replace(render_diagram(connection, diagram_desc, language))
106
- rendered_diag += 1
107
- end
108
- end
86
+ nodes.each do |node|
87
+ # Extract the diagram language from the class list.
88
+ language = node["class"].split.grep(/\Alanguage-/).first.delete_prefix("language-")
89
+ node.replace(render_diagram(connection, node.text, language))
109
90
  end
110
91
 
111
92
  # Convert the document back to HTML.
112
93
  doc.output = parsed_doc.to_html
113
- rendered_diag
94
+ nodes.size
114
95
  end
115
96
 
116
- # Renders a single diagram description using Kroki.
97
+ # Renders a single diagram description using Kroki. The rendered diagram is cached to avoid redundant HTTP
98
+ # requests across documents, using the diagram language and the SHA1 of the diagram description as the key.
117
99
  #
118
100
  # @param [Faraday::Connection] The Faraday connection to use.
119
101
  # @param [String] The diagram description.
120
102
  # @param [String] The language of the diagram description.
121
103
  # @return [String] The rendered diagram in SVG format.
122
- def render_diagram(connection, diagram_desc, language)
123
- begin
124
- response = connection.get("#{language}/svg/#{encode_diagram(diagram_desc.text)}")
125
- rescue Faraday::Error => e
126
- raise e.message
104
+ def render_diagram(connection, diagram_text, language)
105
+ cache_key = "#{language}:#{Digest::SHA1.hexdigest(diagram_text)}"
106
+ @diagram_cache.compute_if_absent(cache_key) do
107
+ response = connection.get("#{language}/svg/#{encode_diagram(diagram_text)}")
108
+ validate_content_type(response)
109
+ sanitise_diagram(response.body)
110
+ rescue Faraday::BadRequestError => e
111
+ kroki_message = e.response_body.to_s.strip
112
+ raise e, (kroki_message.empty? ? e.message : kroki_message)
127
113
  end
114
+ end
115
+
116
+ # Validates that the Kroki response has the expected SVG content type.
117
+ #
118
+ # @param [Faraday::Response] The response to validate.
119
+ def validate_content_type(response)
128
120
  expected_content_type = "image/svg+xml"
129
121
  returned_content_type = response.headers[:content_type]
130
- if returned_content_type != expected_content_type
131
- raise "Kroki returned an incorrect content type: " \
132
- "expected '#{expected_content_type}', received '#{returned_content_type}'"
122
+ return if returned_content_type == expected_content_type
133
123
 
134
- end
135
- sanitise_diagram(response.body)
124
+ raise "[jekyll-kroki] Kroki returned an incorrect content type: " \
125
+ "expected '#{expected_content_type}', received '#{returned_content_type}'"
136
126
  end
137
127
 
138
128
  # Sanitises a rendered diagram. Only <script> elements are removed, which is the most minimal / naive
139
129
  # implementation possible.
140
130
  #
141
- # @param [String] The diagram to santise in SVG format.
131
+ # @param [String] The diagram to sanitise in SVG format.
142
132
  # @return [String] The sanitised diagram.
143
133
  def sanitise_diagram(diagram_svg)
144
134
  parsed_svg = Nokogiri::XML(diagram_svg)
@@ -149,10 +139,10 @@ module Jekyll
149
139
  # Encodes the diagram into Kroki format using deflate + base64.
150
140
  # See https://docs.kroki.io/kroki/setup/encode-diagram/.
151
141
  #
152
- # @param [String, #read] The diagram description to encode.
142
+ # @param [String] The diagram description to encode.
153
143
  # @return [String] The encoded diagram.
154
144
  def encode_diagram(diagram_desc)
155
- Base64.urlsafe_encode64(Zlib.deflate(diagram_desc))
145
+ Base64.urlsafe_encode64(Zlib.deflate(diagram_desc, Zlib::BEST_COMPRESSION))
156
146
  end
157
147
 
158
148
  # Sets up a new Faraday connection.
@@ -175,69 +165,20 @@ module Jekyll
175
165
  end
176
166
  end
177
167
 
178
- # Gets the URL of the Kroki instance to use for rendering diagrams.
179
- #
180
- # @param The Jekyll site configuration.
181
- # @return [URI::HTTP] The URL of the Kroki instance.
182
- def get_kroki_url(config)
183
- url = config.fetch("kroki", {}).fetch("url", DEFAULT_KROKI_URL)
184
- raise TypeError, "'url' is not a valid HTTP URL" unless URI.parse(url).is_a?(URI::HTTP)
185
-
186
- URI(url)
187
- end
188
-
189
- # Gets the number of HTTP retries.
190
- #
191
- # @param The Jekyll site configuration.
192
- # @return [Integer] The number of HTTP retries.
193
- def get_http_retries(config)
194
- config.fetch("kroki", {}).fetch("http_retries", DEFAULT_HTTP_RETRIES)
195
- end
196
-
197
- # Gets the HTTP timeout value.
198
- #
199
- # @param The Jekyll site configuration.
200
- # @return [Integer] The HTTP timeout value in seconds.
201
- def get_http_timeout(config)
202
- config.fetch("kroki", {}).fetch("http_timeout", DEFAULT_HTTP_TIMEOUT)
203
- end
204
-
205
- # Gets the maximum number of documents to render concurrently.
206
- #
207
- # @param The Jekyll site configuration.
208
- # @return [Integer] The maximum number of documents to render concurrently.
209
- def get_max_concurrent_docs(config)
210
- config.fetch("kroki", {}).fetch("max_concurrent_docs", DEFAULT_MAX_CONCURRENT_DOCS)
211
- end
212
-
213
168
  # Determines whether a document may contain embeddable diagram descriptions; it is in HTML format and is either
214
169
  # a Jekyll::Page or writeable Jekyll::Document.
215
170
  #
216
- # @param [Jekyll::Page or Jekyll::Document] The document to check for embeddability.
171
+ # @param [Jekyll::Page or Jekyll::Document] The document to check for embeddable diagrams.
217
172
  def embeddable?(doc)
218
173
  doc.output_ext == ".html" && (doc.is_a?(Jekyll::Page) || doc.write?)
219
174
  end
220
-
221
- # Exits the Jekyll process without returning a stack trace. This method does not return because the process is
222
- # abruptly terminated.
223
- #
224
- # @param [StandardError] The error to display in the termination message.
225
- # @param [int] The caller index to display in the termination message. The default index is 1, which means the
226
- # calling method. To specify the calling method's caller, pass in 2.
227
- #
228
- # Source: https://www.mslinn.com/ruby/2200-crash-exit.html
229
- def exit(error, caller_index = 1)
230
- raise error
231
- rescue StandardError => e
232
- file, line_number, caller = e.backtrace[caller_index].split(":")
233
- caller = caller.tr("", "'")
234
- warn %([jekyll-kroki] "#{error.message}" #{caller} on line #{line_number} of #{file}).red
235
- exec "exit 1"
236
- end
237
175
  end
238
176
  end
239
177
  end
240
178
 
241
179
  Jekyll::Hooks.register :site, :post_render do |site|
242
180
  Jekyll::Kroki.embed_site(site)
181
+ rescue StandardError => e
182
+ Jekyll.logger.error "[jekyll-kroki] #{e.class}: #{e.message}"
183
+ raise
243
184
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-kroki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix van Oost
8
- bindir: exe
8
+ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
@@ -23,6 +23,20 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: '2.25'
26
+ - !ruby/object:Gem::Dependency
27
+ name: concurrent-ruby
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.3'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.3'
26
40
  - !ruby/object:Gem::Dependency
27
41
  name: faraday
28
42
  requirement: !ruby/object:Gem::Requirement
@@ -190,14 +204,13 @@ files:
190
204
  - LICENSE
191
205
  - README.md
192
206
  - Rakefile
193
- - jekyll-kroki.gemspec
194
207
  - lib/jekyll/kroki.rb
208
+ - lib/jekyll/kroki/config.rb
195
209
  - lib/jekyll/kroki/version.rb
196
210
  homepage: https://github.com/felixvanoost/jekyll-kroki
197
211
  licenses:
198
212
  - MIT
199
213
  metadata:
200
- homepage_uri: https://github.com/felixvanoost/jekyll-kroki
201
214
  source_code_uri: https://github.com/felixvanoost/jekyll-kroki
202
215
  rubygems_mfa_required: 'true'
203
216
  rdoc_options: []
@@ -207,14 +220,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
220
  requirements:
208
221
  - - ">="
209
222
  - !ruby/object:Gem::Version
210
- version: 2.7.0
223
+ version: 3.0.0
211
224
  required_rubygems_version: !ruby/object:Gem::Requirement
212
225
  requirements:
213
226
  - - ">="
214
227
  - !ruby/object:Gem::Version
215
228
  version: '0'
216
229
  requirements: []
217
- rubygems_version: 3.6.7
230
+ rubygems_version: 4.0.10
218
231
  specification_version: 4
219
232
  summary: A Jekyll plugin to convert diagram descriptions into images using Kroki
220
233
  test_files: []
data/jekyll-kroki.gemspec DELETED
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/jekyll/kroki/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "jekyll-kroki"
7
- spec.version = Jekyll::Kroki::VERSION
8
- spec.authors = ["Felix van Oost"]
9
-
10
- spec.summary = "A Jekyll plugin to convert diagram descriptions into images using Kroki"
11
- spec.description = "A Jekyll plugin to convert diagram descriptions written in over 25 popular diagram scripting
12
- languages into images using Kroki"
13
- spec.homepage = "https://github.com/felixvanoost/jekyll-kroki"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.7.0"
16
-
17
- spec.metadata["homepage_uri"] = spec.homepage
18
- spec.metadata["source_code_uri"] = spec.homepage
19
- spec.metadata["rubygems_mfa_required"] = "true"
20
-
21
- # Load the files that are versioned in Git into the RubyGem.
22
- spec.files = Dir.chdir(__dir__) do
23
- `git ls-files -z`.split("\x0").reject do |f|
24
- (File.expand_path(f) == __FILE__) ||
25
- f.start_with?(*%w[bin/ test/ spec/ features/ .git appveyor Gemfile])
26
- end
27
- end
28
- spec.bindir = "exe"
29
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
- spec.require_paths = ["lib"]
31
-
32
- spec.add_dependency "async", ["~> 2.25"]
33
- spec.add_dependency "faraday", ["~> 2.7"]
34
- spec.add_dependency "faraday-retry", ["~> 2.2"]
35
- spec.add_dependency "httpx", ["~> 1.1"]
36
- spec.add_dependency "jekyll", ["~> 4"]
37
- spec.add_dependency "nokogiri", ["~> 1.15"]
38
-
39
- spec.add_development_dependency "minitest", ["~> 5.0"]
40
- spec.add_development_dependency "rake", ["~> 13.0"]
41
- spec.add_development_dependency "rubocop", ["~> 1.21"]
42
- spec.add_development_dependency "rubocop-minitest", ["~> 0.38"]
43
- spec.add_development_dependency "rubocop-performance", ["~> 1.25"]
44
- spec.add_development_dependency "rubocop-rake", ["~> 0.7"]
45
- end