Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
galaxyproject
GitHub Repository: galaxyproject/training-material
Path: blob/main/_plugins/snippet.rb
1677 views
1
# frozen_string_literal: true
2
3
require 'yaml'
4
require './_plugins/gtn'
5
6
module Jekyll
7
module Tags
8
# A custom tag {% snippet %} which behaves almost identically to {% include %}
9
# Except that it will render the included file as a proper GTN Box
10
class SnippetIncludeTag < IncludeTag
11
def markdownify(text)
12
@site.find_converter_instance(
13
Jekyll::Converters::Markdown
14
).convert(text.to_s)
15
end
16
17
def get_icon(icon)
18
if icon.start_with?('fa')
19
%(<i class="#{icon}" aria-hidden="true"></i><span class="visually-hidden">#{@text}</span>)
20
elsif icon.start_with?('ai')
21
%(<i class="ai #{icon}" aria-hidden="true"></i><span class="visually-hidden">#{@text}</span>)
22
end
23
end
24
25
def get_config(context)
26
context.registers[:site].config['icon-tag']
27
end
28
29
def render(context)
30
@site ||= context.registers[:site]
31
32
file = render_variable(context) || @file
33
validate_file_name(file)
34
35
# This doesn't feel right, we should've been able to figure it out in
36
# render_variable(context) but it's not clear why that doesn't work.
37
begin
38
@site.inclusions[file] ||= locate_include_file(file)
39
rescue StandardError
40
@site.inclusions[file] ||= locate_include_file(context[file])
41
end
42
43
inclusion = @site.inclusions[file]
44
45
add_include_to_dependency(inclusion, context) if @site.config['incremental']
46
47
context.stack do
48
context['include'] = parse_params(context) if @params
49
x = inclusion.render(context).to_s
50
p = context['include']
51
52
box_start = ''
53
box_end = ''
54
if x.slice(0, 3) == '---'
55
metadata = YAML.safe_load(x)
56
57
# allow overriding box type with include parameter ("none" to render without a box)
58
box_type = if !p.nil? && p['box_type']
59
p['box_type']
60
else
61
metadata['box_type']
62
end
63
64
# Allow overriding the title with an include parameter
65
title = if !p.nil? && p['override_title']
66
p['override_title']
67
else
68
metadata['title']
69
end
70
71
if context.registers[:page]&.key?('lang')
72
lang = context.registers[:page].fetch('lang', 'en')
73
lang = 'en' if lang.nil?
74
end
75
lang = 'en' if lang.nil?
76
if (box_type != 'none') && !box_type.nil?
77
_box_id, box_title = Gtn::Boxify.generate_title(box_type, title, lang,
78
context.registers[:page]['path'])
79
box_start = "> #{box_title}"
80
box_end = "\n{: .#{box_type}}"
81
end
82
end
83
y = x.split("\n---\n", 2).last
84
# if y =~ /contribute/
85
# puts "=== step 1 ===\n#{y}\n\n"
86
# end
87
z = markdownify(y)
88
# if z =~ /contribute/
89
# puts "=== step 2 ===\n#{z}\n\n"
90
# end
91
if box_start != ''
92
z = z.gsub(/\R/, "\n> ")
93
# puts box_start+y+box_end
94
end
95
96
# if z =~ /contribute/
97
# puts "=== step 3 ===\n#{z}\n\n"
98
# puts "=== MARKDOWN ===\n#{box_start+z+box_end}\n\n"
99
# puts "=== RENDERED ===\n#{markdownify(box_start+z+box_end)}\n\n"
100
# end
101
102
final_box_text = markdownify(box_start + z + box_end)
103
# Replace newlines inside of a PRE with <br>, so they don't get eaten during next one.
104
.gsub(%r{<(pre)[^>]*>(.*?)</\1>}m) { |m| m.gsub(/\n/, '<br>') }
105
# Strip out spaces or the boxes break, replace
106
# them with single spaces so e.g. newlines get collapsed into a space
107
# and don't merge words together that shouldn't be merged.
108
.gsub(/\R+/, ' ')
109
.gsub('<h3', '<h3 data-toc-skip')
110
"<!--SNIPPET-->#{final_box_text}<!--END_SNIPPET-->"
111
end
112
end
113
114
private
115
116
def locate_include_file(file)
117
@site.includes_load_paths.each do |dir|
118
path = PathManager.join(dir, file)
119
return Inclusion.new(@site, dir, file) if valid_include_file?(path, dir)
120
end
121
raise IOError, could_not_locate_message(file, @site.includes_load_paths, @site.safe)
122
end
123
124
def valid_include_file?(path, dir)
125
File.file?(path) && !outside_scope?(path, dir)
126
end
127
128
def outside_scope?(path, dir)
129
@site.safe && !realpath_prefixed_with?(path, dir)
130
end
131
132
def realpath_prefixed_with?(path, dir)
133
File.realpath(path).start_with?(dir)
134
rescue StandardError
135
false
136
end
137
138
def add_include_to_dependency(inclusion, context)
139
return unless context.registers[:page]&.key?('path')
140
141
@site.regenerator.add_dependency(
142
@site.in_source_dir(context.registers[:page]['path']),
143
inclusion.path
144
)
145
end
146
end
147
end
148
end
149
150
Liquid::Template.register_tag('snippet', Jekyll::Tags::SnippetIncludeTag)
151
152
Jekyll::Hooks.register :pages, :post_render do |page|
153
if page.output =~ /-title>/
154
page.output = Gtn::Boxify.replace_elements(page.output, page.data.fetch('lang', 'en'), page.path)
155
end
156
end
157
158