Module: Jekyll::Shiki
- Defined in:
- lib/jekyll-shiki.rb,
lib/version.rb
Overview
module Jekyll::ShikiCodeBlock
Constant Summary collapse
- VERSION =
"0.1.1"
Class Method Summary collapse
- .create_wrapper(lan, code, site) ⇒ Object
- .full_document?(html_content) ⇒ Boolean
- .replace_elements(node, site) ⇒ Object
- .resolve_shiki_bundle_path(site) ⇒ Object
- .shiki_highlight(code, lang, site) ⇒ Object
- .transform_html(html_content, site) ⇒ Object
Class Method Details
.create_wrapper(lan, code, site) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/jekyll-shiki.rb', line 39 def self.create_wrapper(lan, code, site) lang = lan.capitalize highlighted_code = shiki_highlight(code, lan, site) <<~HTML <div class="shiki_code" data-shiki-highlighter> <div class="code_head"> <span>#{lan}</span> <button type="button" aria-label="Highlight-#{lang}" data-copy-btn></button> </div> #{highlighted_code} </div> HTML end |
.full_document?(html_content) ⇒ Boolean
66 67 68 |
# File 'lib/jekyll-shiki.rb', line 66 def self.full_document?(html_content) html_content.match?(/\A\s*(<!doctype\s+html|<html\b)/i) end |
.replace_elements(node, site) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/jekyll-shiki.rb', line 53 def self.replace_elements(node, site) code_el = node.at_css('> code[class^="language-"]') return unless code_el code = code_el.text lang = code_el["class"] &.split &.find { |class_name| class_name.start_with?("language-") } &.delete_prefix("language-") fragment = Nokogiri::HTML::DocumentFragment.parse(create_wrapper(lang, code, site)) node.replace(fragment) end |
.resolve_shiki_bundle_path(site) ⇒ Object
16 17 18 19 20 21 22 23 24 |
# File 'lib/jekyll-shiki.rb', line 16 def self.resolve_shiki_bundle_path(site) shiki_config = site.config["shiki"] raise "Shiki highlight failed: Shiki config not found in jekyll config" unless shiki_config bundle_path = shiki_config["file_path"] raise "Shiki highlight failed: Required shiki bundle path." unless bundle_path File.join(site.source, bundle_path) end |
.shiki_highlight(code, lang, site) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/jekyll-shiki.rb', line 26 def self.shiki_highlight(code, lang, site) script_path = resolve_shiki_bundle_path(site) cache_key = Digest::SHA256.hexdigest("#{lang}::#{code}") Jekyll::Cache.new("Shiki").getset(cache_key) do input = JSON.generate({ code: code, lang: lang }.compact) stdout, stderr, status = Open3.capture3("node", script_path, stdin_data: input) raise "Shiki highlight failed: #{stderr}" unless status.success? stdout end end |
.transform_html(html_content, site) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/jekyll-shiki.rb', line 70 def self.transform_html(html_content, site) doc = if full_document?(html_content) Nokogiri::HTML.parse(html_content) else Nokogiri::HTML::DocumentFragment.parse(html_content) end elements = doc.css("pre").select { |pre| pre.at_css('> code[class^="language-"]') } return html_content if elements.empty? elements.each { |node| replace_elements(node, site) } doc.to_html end |