Skip to content

Commit f0a110f

Browse files
authored
添加 kramdown_enhancer 插件 (#435)
1 parent 0278979 commit f0a110f

16 files changed

Lines changed: 177 additions & 97 deletions

.github/workflows/pr-preview.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ concurrency:
1010
group: pr-preview
1111
cancel-in-progress: false
1212
env:
13-
GITHUB_PR_NUMBER: ${{ github.event_name == 'issue_comment' && github.event.issue.number || github.event.pull_request.number }}
1413
JEKYLL_ENV: production
14+
ENABLE_WEBP_AUTO_CONVERSION: "true"
15+
GITHUB_PR_NUMBER: ${{ github.event_name == 'issue_comment' && github.event.issue.number || github.event.pull_request.number }}
1516
jobs:
1617
cache-refresh:
1718
if: ${{ !github.event.repository.fork && github.event_name == 'schedule' && github.event.schedule == '0 0 */6 * *' }}

Gemfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,4 @@ gem "wdm", "0.2.0", :platforms => [:windows]
3232
gem "http_parser.rb", "0.8.0", :platforms => [:jruby]
3333

3434
# plugin dependencies
35-
gem "nokogiri", "1.19.1"
36-
gem "addressable", "2.8.7"
35+
gem "webp-ffi", "0.4.0" if ENV["ENABLE_WEBP_AUTO_CONVERSION"] == "true" || ENV["DRONE"] == "true"

_data/plugins/auto_alert.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

_plugins/auto-alert.rb

Lines changed: 0 additions & 48 deletions
This file was deleted.

_plugins/auto-link.rb

Lines changed: 0 additions & 30 deletions
This file was deleted.

_plugins/kramdown_enhancer.rb

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
begin
2+
require "webp-ffi"
3+
rescue LoadError; end
4+
5+
module KramdownEnhancer
6+
class << self
7+
def webp
8+
@webp ||= {}
9+
end
10+
11+
def file
12+
@file ||= {}
13+
end
14+
15+
def baseurl
16+
@baseurl
17+
end
18+
19+
def baseurl=(input)
20+
@baseurl =
21+
if input.is_a?(String) && !input.empty?
22+
str = input.start_with?("/") ? input : "/#{input}"
23+
str.chomp("/")
24+
else
25+
""
26+
end
27+
end
28+
29+
def blockquote_types
30+
@blockquote_types ||= {
31+
:note => "notice--info",
32+
:tip => "notice--success",
33+
:important => "notice--primary",
34+
:warning => "notice--warning",
35+
:caution => "notice--danger",
36+
}
37+
end
38+
end
39+
40+
class WebpFile < Jekyll::StaticFile
41+
def write(dest)
42+
true
43+
end
44+
end
45+
46+
module Html
47+
def convert_a(el, indent)
48+
if el.attr["href"].is_a?(String) && !el.options[:relative]
49+
el.attr["href"] = relative_url(el.attr["href"])
50+
el.options[:relative] = true
51+
end
52+
53+
super
54+
end
55+
56+
def convert_img(el, indent)
57+
if el.attr["src"].is_a?(String) && !el.options[:relative]
58+
src = el.attr["src"]
59+
el.attr["src"] = relative_url(src)
60+
el.options[:relative] = true
61+
62+
if KramdownEnhancer.webp[src] && !el.options[:webp] && !el.options[:picture]
63+
webp_src = KramdownEnhancer.webp[src]
64+
pic = Kramdown::Element.new(:html_element, "picture")
65+
pic.children << Kramdown::Element.new(:html_element, "source", { "srcset" => relative_url(webp_src), "type" => "image/webp" })
66+
el.options[:picture] = true
67+
el.options[:webp] = true
68+
pic.children << el
69+
return convert_html_element(pic, indent)
70+
end
71+
end
72+
73+
super
74+
end
75+
76+
def convert_blockquote(el, indent)
77+
p = el.children.first
78+
return super if p&.type != :p || p.children.empty?
79+
80+
first = p.children.first
81+
return super unless first&.type == :text
82+
83+
text = first.value.downcase
84+
KramdownEnhancer.blockquote_types.each do |type, class_name|
85+
prefix = "[!#{type}]"
86+
prefix_with_newline = "#{prefix}\n"
87+
88+
# case A: <p>[!NOTE]</p>
89+
if text == prefix
90+
el.attr["class"] = [el.attr["class"], class_name].compact.join(" ")
91+
p.children.shift
92+
break
93+
# case B: <p>[!NOTE]\n some text</p>
94+
elsif text.start_with?(prefix_with_newline)
95+
el.attr["class"] = [el.attr["class"], class_name].compact.join(" ")
96+
first.value = first.value[prefix_with_newline.length..-1] || ""
97+
break
98+
end
99+
end
100+
101+
super
102+
end
103+
104+
def convert_html_element(el, indent)
105+
unless el.options[:relative]
106+
if el.value == "a" && el.attr["href"].is_a?(String)
107+
el.attr["href"] = relative_url(el.attr["href"])
108+
el.options[:relative] = true
109+
elsif el.value == "img" && el.attr["src"].is_a?(String)
110+
src = el.attr["src"]
111+
el.attr["src"] = relative_url(el.attr["src"])
112+
el.options[:relative] = true
113+
114+
if KramdownEnhancer.webp[src] && !el.options[:webp] && !el.options[:picture]
115+
webp_src = KramdownEnhancer.webp[src]
116+
pic = Kramdown::Element.new(:html_element, "picture")
117+
pic.children << Kramdown::Element.new(:html_element, "source", { "srcset" => relative_url(webp_src), "type" => "image/webp" })
118+
el.options[:webp] = true
119+
pic.children << el
120+
return convert_html_element(pic, indent)
121+
end
122+
elsif el.value == "picture"
123+
el.children.each do |child|
124+
child.options[:picture] = true
125+
end
126+
end
127+
end
128+
super(el, indent)
129+
end
130+
131+
private
132+
133+
def relative_url(input)
134+
if input.is_a?(String) && input.start_with?("/")
135+
input = input.start_with?("/") ? input : "/#{input}"
136+
uri = Addressable::URI.parse(input)
137+
if uri
138+
if uri.path.length > 1
139+
file = KramdownEnhancer.file[uri.path[1..]]
140+
uri.path = file.url if file
141+
end
142+
uri.path = "#{KramdownEnhancer.baseurl}#{uri.path}"
143+
return uri.to_s
144+
end
145+
end
146+
input
147+
end
148+
end
149+
end
150+
151+
Jekyll::Hooks.register :site, :post_read do |site|
152+
KramdownEnhancer.baseurl = site.config["baseurl"]
153+
webp_list = []
154+
webp_enabled = defined?(WebP)
155+
site.each_site_file do |file|
156+
KramdownEnhancer.file[file.relative_path] = file
157+
if file.is_a?(Jekyll::StaticFile)
158+
url = "#{file.url}.webp"
159+
source = "#{file.path}.webp"
160+
destination = File.join(site.dest, url)
161+
if File.exist?(source)
162+
KramdownEnhancer.webp[file.url] = url
163+
elsif webp_enabled && %w[.png .jpg .jpeg .tif .tiff].include?(file.extname.downcase)
164+
FileUtils.mkdir_p(File.dirname(destination))
165+
WebP.encode(file.path, destination)
166+
webp_list.push(KramdownEnhancer::WebpFile.new(site, site.dest, File.dirname(url), File.basename(url)))
167+
KramdownEnhancer.webp[file.url] = url
168+
end
169+
end
170+
end
171+
site.static_files.concat(webp_list)
172+
Kramdown::Converter::Html.prepend(KramdownEnhancer::Html)
173+
end
3.7 MB
Loading
2.23 MB
Loading
870 KB
Loading
861 KB
Loading

0 commit comments

Comments
 (0)