Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
galaxyproject
GitHub Repository: galaxyproject/training-material
Path: blob/main/_plugins/jekyll-figurify.rb
1677 views
1
# frozen_string_literal: true
2
3
require 'jekyll'
4
5
module Jekyll
6
module Generators
7
# Our modifications to the markdown renderer to process images with figure captions
8
# TODO: probably could be a hook post_read.
9
class Figurify < Jekyll::Generator
10
safe true
11
12
def initialize(config)
13
super
14
@config = config['figurify'] ||= {}
15
end
16
17
def generate(site)
18
site.pages
19
.reject { |page| skip_layout? page.data['layout'] }
20
.each { |page| figurify page, site }
21
site.posts.docs
22
.reject { |post| skip_layout? post.data['layout'] }
23
.each { |post| figurify post, site }
24
end
25
26
private
27
28
def insert_image(url, alt, style, dimensions, actual_path)
29
# If it's a *local* SVG (we don't want to do this with remote SVGs, doesn't work right)
30
if url =~ (/svg$/) && !actual_path.nil?
31
fallback = ''
32
if actual_path.nil?
33
# External image, no fallback possible
34
fallback = ''
35
elsif File.exist?(actual_path.gsub(/svg$/, 'png'))
36
fallback = "<img src=\"#{url.gsub(/svg$/, 'png')}\" alt=\"#{alt}\">"
37
elsif File.exist?(actual_path.gsub(/svg$/, 'jpg'))
38
fallback = "<img src=\"#{url.gsub(/svg$/, 'jpg')}\" alt=\"#{alt}\">"
39
elsif File.exist?(actual_path.gsub(/svg$/, 'jpeg'))
40
fallback = "<img src=\"#{url.gsub(/svg$/, 'jpeg')}\" alt=\"#{alt}\">"
41
end
42
43
%(
44
<div style="overflow-x: auto">
45
<object data="#{url}" #{style} type="image/svg+xml" alt="#{alt}">
46
#{fallback}
47
#{alt}
48
</object>
49
</div>
50
)
51
else
52
%(
53
<img src="#{url}" alt="#{alt}" #{style} #{dimensions} loading="lazy">
54
)
55
end
56
end
57
58
def figurify(page, site)
59
num_figure = 0
60
return if page.content.nil?
61
62
tuto_dir = File.dirname(page.path)
63
page.content = page.content.gsub(/!\[([^\]]*)\]\((.+?)\s*(?:"(.*)")\)({:(.*)})?/) do
64
alt = ::Regexp.last_match(1)
65
url = ::Regexp.last_match(2)
66
title = ::Regexp.last_match(3)
67
style = ::Regexp.last_match(5)
68
69
if skip_titles?(title) || (title.to_s.empty? && skip_empty?)
70
Regexp.last_match
71
else
72
num_figure += 1
73
74
alt.gsub!(/"/, '&quot;')
75
if alt.strip.length.positive? && !(alt.end_with?('.') || alt.end_with?('!') || alt.end_with?('?'))
76
alt = "#{alt}. "
77
end
78
79
dimensions, actual_path = Gtn::Images.html_image_dimensions(tuto_dir, url)
80
prefix = figcaption_prefix(page, site)
81
image = insert_image(url, alt, style, dimensions, actual_path)
82
83
%(
84
<figure id="figure-#{num_figure}" style="max-width: 90%;">
85
#{image}
86
<a target="_blank" href="#{url}" rel="noopener noreferrer"><small>Open image in new tab</small></a><br/><br/>
87
<figcaption>
88
<span class="figcaption-prefix"><strong>#{prefix}#{num_figure}</strong>:</span> #{title}
89
</figcaption>
90
</figure>
91
).split("\n").map(&:strip).join
92
end
93
end
94
95
page.content = page.content.gsub(/!\[([^\]]*)\]\((.+?)?\)({:(.*)})?/) do
96
alt = ::Regexp.last_match(1)
97
url = ::Regexp.last_match(2)
98
style = ::Regexp.last_match(4)
99
100
dimensions, _actual_path = Gtn::Images.html_image_dimensions(tuto_dir, url)
101
102
alt.gsub!(/"/, '&quot;')
103
if alt.strip.length.positive? && !(alt.end_with?('.') || alt.end_with?('!') || alt.end_with?('?'))
104
alt = "#{alt}. "
105
end
106
107
%(
108
<a href="#{url}" rel="noopener noreferrer">
109
<img src="#{url}" alt="#{alt}" #{style} #{dimensions} loading="lazy">
110
</a>
111
).split("\n").map(&:strip).join
112
end
113
end
114
115
def figcaption_prefix(page, site)
116
fig = 'Figure'
117
if page['lang']
118
lang = page['lang']
119
fig = site.data['lang'][lang]['figure']
120
end
121
@config['prefix'] || "#{fig} "
122
end
123
124
def skip_empty?
125
@config['skip_empty'] || false
126
end
127
128
def skip_layout?(layout)
129
to_skip = @config['skip_layouts'] || []
130
131
true if to_skip.empty?
132
133
to_skip.include?(layout)
134
end
135
136
def skip_titles?(title)
137
to_skip = @config['skip_titles'] || []
138
to_skip.include?(title)
139
end
140
end
141
end
142
end
143
144