添加 kramdown_enhancer 插件 (#435)
All checks were successful
continuous-integration/drone/push Build is passing
3
.github/workflows/pr-preview.yml
vendored
@ -10,8 +10,9 @@ concurrency:
|
|||||||
group: pr-preview
|
group: pr-preview
|
||||||
cancel-in-progress: false
|
cancel-in-progress: false
|
||||||
env:
|
env:
|
||||||
GITHUB_PR_NUMBER: ${{ github.event_name == 'issue_comment' && github.event.issue.number || github.event.pull_request.number }}
|
|
||||||
JEKYLL_ENV: production
|
JEKYLL_ENV: production
|
||||||
|
ENABLE_WEBP_AUTO_CONVERSION: "true"
|
||||||
|
GITHUB_PR_NUMBER: ${{ github.event_name == 'issue_comment' && github.event.issue.number || github.event.pull_request.number }}
|
||||||
jobs:
|
jobs:
|
||||||
cache-refresh:
|
cache-refresh:
|
||||||
if: ${{ !github.event.repository.fork && github.event_name == 'schedule' && github.event.schedule == '0 0 */6 * *' }}
|
if: ${{ !github.event.repository.fork && github.event_name == 'schedule' && github.event.schedule == '0 0 */6 * *' }}
|
||||||
|
|||||||
3
Gemfile
@ -32,5 +32,4 @@ gem "wdm", "0.2.0", :platforms => [:windows]
|
|||||||
gem "http_parser.rb", "0.8.0", :platforms => [:jruby]
|
gem "http_parser.rb", "0.8.0", :platforms => [:jruby]
|
||||||
|
|
||||||
# plugin dependencies
|
# plugin dependencies
|
||||||
gem "nokogiri", "1.19.1"
|
gem "webp-ffi", "0.4.0" if ENV["ENABLE_WEBP_AUTO_CONVERSION"] == "true" || ENV["DRONE"] == "true"
|
||||||
gem "addressable", "2.8.7"
|
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
note:
|
|
||||||
title: 注意
|
|
||||||
class_name: notice--info
|
|
||||||
tip:
|
|
||||||
title: 提示
|
|
||||||
class_name: notice--success
|
|
||||||
important:
|
|
||||||
title: 重要
|
|
||||||
class_name: notice--primary
|
|
||||||
warning:
|
|
||||||
title: 警告
|
|
||||||
class_name: notice--warning
|
|
||||||
caution:
|
|
||||||
title: 谨慎
|
|
||||||
class_name: notice--danger
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
require "nokogiri"
|
|
||||||
|
|
||||||
Jekyll::Hooks.register [:pages, :documents], :post_convert do |doc|
|
|
||||||
next unless doc.output_ext == ".html"
|
|
||||||
site = doc.site
|
|
||||||
next unless site.data["plugins"]
|
|
||||||
alert_type = site.data["plugins"]["auto_alert"]
|
|
||||||
next unless alert_type
|
|
||||||
|
|
||||||
fragment = Nokogiri::HTML::DocumentFragment.parse(doc.content)
|
|
||||||
# 遍历 HTML 中的所有 blockquote 标签
|
|
||||||
fragment.css("blockquote").each do |item|
|
|
||||||
# 找出第一个子节点,用于判断是否含有 [!type] 标记
|
|
||||||
first_child = item.at_css("*:first-child")
|
|
||||||
next unless first_child
|
|
||||||
next unless first_child.name == "p"
|
|
||||||
|
|
||||||
inner_html = first_child.inner_html.downcase
|
|
||||||
|
|
||||||
# 遍历所有 alert 类型
|
|
||||||
alert_type.each do |type, data|
|
|
||||||
prefix = "[!#{type}]"
|
|
||||||
prefix_with_newline = "#{prefix}\n"
|
|
||||||
|
|
||||||
# 情况一:完整匹配 [!type] 形式 <p>[!NOTE]</p>
|
|
||||||
if inner_html == prefix
|
|
||||||
# 将 alert 类型对应的 class 加入 blockquote
|
|
||||||
item["class"] = [item["class"], data["class_name"]].compact.join(" ")
|
|
||||||
|
|
||||||
# 将 <p> 替换为 <div> 并插入标题
|
|
||||||
first_child.name = "div"
|
|
||||||
first_child.inner_html = "<strong>#{data["title"]}</strong>"
|
|
||||||
break
|
|
||||||
|
|
||||||
# 情况二:段落以 [!type]\n 开头 <p>[!NOTE]\n\n other content</p>
|
|
||||||
elsif inner_html.start_with? prefix_with_newline
|
|
||||||
# 将 alert 类型对应的 class 加入 blockquote
|
|
||||||
item["class"] = [item["class"], data["class_name"]].compact.join(" ")
|
|
||||||
# 在原段落前插入标题 <div><strong>提示</strong></div><p>[!NOTE]\n\n other content</p>
|
|
||||||
first_child.add_previous_sibling "<div><strong>#{data["title"]}</strong></div>"
|
|
||||||
# 移除段落内容开头的 [!type]\n <div><strong>提示</strong></div><p>\n other content</p>
|
|
||||||
first_child.inner_html = first_child.inner_html[prefix_with_newline.length..-1] || ""
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
doc.content = fragment.to_html
|
|
||||||
end
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
require "nokogiri"
|
|
||||||
require "addressable/uri"
|
|
||||||
|
|
||||||
Jekyll::Hooks.register [:pages, :documents], :post_convert do |doc|
|
|
||||||
next unless doc.output_ext == ".html"
|
|
||||||
|
|
||||||
site = doc.site
|
|
||||||
liquid_context = Liquid::Context.new({}, {}, { site: site })
|
|
||||||
|
|
||||||
process_uri = lambda do |path|
|
|
||||||
uri = Addressable::URI.parse(path)
|
|
||||||
if uri&.path
|
|
||||||
uri.path = Liquid::Template.parse("{% link #{uri.path[1..]} %}").render!(liquid_context)
|
|
||||||
end
|
|
||||||
uri.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
fragment = Nokogiri::HTML::DocumentFragment.parse(doc.content)
|
|
||||||
fragment.css("[src^=\"/assets/\"],[src^=\"/\"][src$=\".md\"],[src^=\"/\"][src*=\".md#\"]").each do |item|
|
|
||||||
if item["src"]
|
|
||||||
item["src"] = process_uri.call(item["src"])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
fragment.css("[href^=\"/assets/\"],[href^=\"/\"][href$=\".md\"],[href^=\"/\"][href*=\".md#\"]").each do |item|
|
|
||||||
if item["href"]
|
|
||||||
item["href"] = process_uri.call(item["href"])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
doc.content = fragment.to_html
|
|
||||||
end
|
|
||||||
173
_plugins/kramdown_enhancer.rb
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
begin
|
||||||
|
require "webp-ffi"
|
||||||
|
rescue LoadError; end
|
||||||
|
|
||||||
|
module KramdownEnhancer
|
||||||
|
class << self
|
||||||
|
def webp
|
||||||
|
@webp ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def file
|
||||||
|
@file ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def baseurl
|
||||||
|
@baseurl
|
||||||
|
end
|
||||||
|
|
||||||
|
def baseurl=(input)
|
||||||
|
@baseurl =
|
||||||
|
if input.is_a?(String) && !input.empty?
|
||||||
|
str = input.start_with?("/") ? input : "/#{input}"
|
||||||
|
str.chomp("/")
|
||||||
|
else
|
||||||
|
""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def blockquote_types
|
||||||
|
@blockquote_types ||= {
|
||||||
|
:note => "notice--info",
|
||||||
|
:tip => "notice--success",
|
||||||
|
:important => "notice--primary",
|
||||||
|
:warning => "notice--warning",
|
||||||
|
:caution => "notice--danger",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class WebpFile < Jekyll::StaticFile
|
||||||
|
def write(dest)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Html
|
||||||
|
def convert_a(el, indent)
|
||||||
|
if el.attr["href"].is_a?(String) && !el.options[:relative]
|
||||||
|
el.attr["href"] = relative_url(el.attr["href"])
|
||||||
|
el.options[:relative] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_img(el, indent)
|
||||||
|
if el.attr["src"].is_a?(String) && !el.options[:relative]
|
||||||
|
src = el.attr["src"]
|
||||||
|
el.attr["src"] = relative_url(src)
|
||||||
|
el.options[:relative] = true
|
||||||
|
|
||||||
|
if KramdownEnhancer.webp[src] && !el.options[:webp] && !el.options[:picture]
|
||||||
|
webp_src = KramdownEnhancer.webp[src]
|
||||||
|
pic = Kramdown::Element.new(:html_element, "picture")
|
||||||
|
pic.children << Kramdown::Element.new(:html_element, "source", { "srcset" => relative_url(webp_src), "type" => "image/webp" })
|
||||||
|
el.options[:picture] = true
|
||||||
|
el.options[:webp] = true
|
||||||
|
pic.children << el
|
||||||
|
return convert_html_element(pic, indent)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_blockquote(el, indent)
|
||||||
|
p = el.children.first
|
||||||
|
return super if p&.type != :p || p.children.empty?
|
||||||
|
|
||||||
|
first = p.children.first
|
||||||
|
return super unless first&.type == :text
|
||||||
|
|
||||||
|
text = first.value.downcase
|
||||||
|
KramdownEnhancer.blockquote_types.each do |type, class_name|
|
||||||
|
prefix = "[!#{type}]"
|
||||||
|
prefix_with_newline = "#{prefix}\n"
|
||||||
|
|
||||||
|
# case A: <p>[!NOTE]</p>
|
||||||
|
if text == prefix
|
||||||
|
el.attr["class"] = [el.attr["class"], class_name].compact.join(" ")
|
||||||
|
p.children.shift
|
||||||
|
break
|
||||||
|
# case B: <p>[!NOTE]\n some text</p>
|
||||||
|
elsif text.start_with?(prefix_with_newline)
|
||||||
|
el.attr["class"] = [el.attr["class"], class_name].compact.join(" ")
|
||||||
|
first.value = first.value[prefix_with_newline.length..-1] || ""
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_html_element(el, indent)
|
||||||
|
unless el.options[:relative]
|
||||||
|
if el.value == "a" && el.attr["href"].is_a?(String)
|
||||||
|
el.attr["href"] = relative_url(el.attr["href"])
|
||||||
|
el.options[:relative] = true
|
||||||
|
elsif el.value == "img" && el.attr["src"].is_a?(String)
|
||||||
|
src = el.attr["src"]
|
||||||
|
el.attr["src"] = relative_url(el.attr["src"])
|
||||||
|
el.options[:relative] = true
|
||||||
|
|
||||||
|
if KramdownEnhancer.webp[src] && !el.options[:webp] && !el.options[:picture]
|
||||||
|
webp_src = KramdownEnhancer.webp[src]
|
||||||
|
pic = Kramdown::Element.new(:html_element, "picture")
|
||||||
|
pic.children << Kramdown::Element.new(:html_element, "source", { "srcset" => relative_url(webp_src), "type" => "image/webp" })
|
||||||
|
el.options[:webp] = true
|
||||||
|
pic.children << el
|
||||||
|
return convert_html_element(pic, indent)
|
||||||
|
end
|
||||||
|
elsif el.value == "picture"
|
||||||
|
el.children.each do |child|
|
||||||
|
child.options[:picture] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
super(el, indent)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def relative_url(input)
|
||||||
|
if input.is_a?(String) && input.start_with?("/")
|
||||||
|
input = input.start_with?("/") ? input : "/#{input}"
|
||||||
|
uri = Addressable::URI.parse(input)
|
||||||
|
if uri
|
||||||
|
if uri.path.length > 1
|
||||||
|
file = KramdownEnhancer.file[uri.path[1..]]
|
||||||
|
uri.path = file.url if file
|
||||||
|
end
|
||||||
|
uri.path = "#{KramdownEnhancer.baseurl}#{uri.path}"
|
||||||
|
return uri.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
input
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Jekyll::Hooks.register :site, :post_read do |site|
|
||||||
|
KramdownEnhancer.baseurl = site.config["baseurl"]
|
||||||
|
webp_list = []
|
||||||
|
webp_enabled = defined?(WebP)
|
||||||
|
site.each_site_file do |file|
|
||||||
|
KramdownEnhancer.file[file.relative_path] = file
|
||||||
|
if file.is_a?(Jekyll::StaticFile)
|
||||||
|
url = "#{file.url}.webp"
|
||||||
|
source = "#{file.path}.webp"
|
||||||
|
destination = File.join(site.dest, url)
|
||||||
|
if File.exist?(source)
|
||||||
|
KramdownEnhancer.webp[file.url] = url
|
||||||
|
elsif webp_enabled && %w[.png .jpg .jpeg .tif .tiff].include?(file.extname.downcase)
|
||||||
|
FileUtils.mkdir_p(File.dirname(destination))
|
||||||
|
WebP.encode(file.path, destination)
|
||||||
|
webp_list.push(KramdownEnhancer::WebpFile.new(site, site.dest, File.dirname(url), File.basename(url)))
|
||||||
|
KramdownEnhancer.webp[file.url] = url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
site.static_files.concat(webp_list)
|
||||||
|
Kramdown::Converter::Html.prepend(KramdownEnhancer::Html)
|
||||||
|
end
|
||||||
BIN
assets/img/docs/fabric_and_optifine_install/1.gif.webp
Normal file
|
After Width: | Height: | Size: 3.7 MiB |
BIN
assets/img/docs/fabric_and_optifine_install/11.gif.webp
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
assets/img/docs/java-download-pages/macos-arm64-1.gif.webp
Normal file
|
After Width: | Height: | Size: 870 KiB |
BIN
assets/img/docs/java-download-pages/macos-x86_64-1.gif.webp
Normal file
|
After Width: | Height: | Size: 860 KiB |
BIN
assets/img/docs/java-download-pages/windows-x86-1.gif.webp
Normal file
|
After Width: | Height: | Size: 809 KiB |
BIN
assets/img/docs/java-download-pages/windows-x86-2.gif.webp
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
assets/img/docs/java-download-pages/windows-x86-3.gif.webp
Normal file
|
After Width: | Height: | Size: 306 KiB |
BIN
assets/img/docs/java-download-pages/windows-x86_64-1.gif.webp
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
assets/img/docs/java-download-pages/windows-x86_64-2.gif.webp
Normal file
|
After Width: | Height: | Size: 459 KiB |
2
index.md
@ -23,7 +23,7 @@ title: 新手导航
|
|||||||
{% for group in site.data.navigation.docs -%}
|
{% for group in site.data.navigation.docs -%}
|
||||||
## {{ group.title }}
|
## {{ group.title }}
|
||||||
{% for item in group.children -%}
|
{% for item in group.children -%}
|
||||||
1. [{{ item.title }}]({{ item.url | relative_url }})
|
1. [{{ item.title }}]({{ item.url }})
|
||||||
{%- if item.description %}\
|
{%- if item.description %}\
|
||||||
{{ item.description }}
|
{{ item.description }}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|||||||