From 70a2c42a5eef1dab2b7ab75e3c7f6ffc8c8c1959 Mon Sep 17 00:00:00 2001 From: Patrick Spek Date: Fri, 5 Feb 2021 09:55:25 +0100 Subject: Move source files into src --- src/_plugins/highlight.rb | 127 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/_plugins/highlight.rb (limited to 'src/_plugins/highlight.rb') diff --git a/src/_plugins/highlight.rb b/src/_plugins/highlight.rb new file mode 100644 index 0000000..d59140c --- /dev/null +++ b/src/_plugins/highlight.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +module Jekyll + module Tags + class HighlightBlock < Liquid::Block + include Liquid::StandardFilters + + def initialize(tag_name, markup, tokens) + super + + opts = markup.split + @opts = Hash.new + @lang = opts.shift.downcase + + opts.each do |opt| + if opt.include?("=") + parts = opt.split("=", 2) + + @opts[parts[0]] = parts[1] + end + + @opts[opt] = true + end + end + + def render(context) + prefix = context["highlighter_prefix"] || "" + suffix = context["highlighter_suffix"] || "" + code = super.to_s.gsub(%r!\A(\n|\r)+|(\n|\r)+\z!, "") + + is_safe = !!context.registers[:site].safe + + output = + case context.registers[:site].highlighter + when "pygments" + render_pygments(code, is_safe) + when "rouge" + render_rouge(code) + else + render_codehighlighter(code) + end + + rendered_output = add_code_tag(output) + prefix + rendered_output + suffix + end + + def sanitized_opts(opts, is_safe) + if is_safe + Hash[[ + [:startinline, opts.fetch(:startinline, nil)], + [:hl_lines, opts.fetch(:hl_lines, nil)], + [:linenos, opts.fetch(:linenos, nil)], + [:encoding, opts.fetch(:encoding, "utf-8")], + [:cssclass, opts.fetch(:cssclass, nil)], + ].reject { |f| f.last.nil? }] + else + opts + end + end + + private + + def render_pygments(code, is_safe) + Jekyll::External.require_with_graceful_fail("pygments") unless defined?(Pygments) + + highlighted_code = Pygments.highlight( + code, + :lexer => @lang, + :options => sanitized_opts(@highlight_options, is_safe) + ) + + if highlighted_code.nil? + Jekyll.logger.error <<~MSG + There was an error highlighting your code: + + #{code} + + While attempting to convert the above code, Pygments.rb returned an unacceptable value. + This is usually a timeout problem solved by running `jekyll build` again. + MSG + raise ArgumentError, "Pygments.rb returned an unacceptable value "\ + "when attempting to highlight some code." + end + + highlighted_code.sub('
', "").sub("
", "") + end + + def render_rouge(code) + require "rouge" + formatter = ::Rouge::Formatters::HTMLLegacy.new( + :line_numbers => @highlight_options[:linenos], + :wrap => false, + :css_class => "highlight", + :gutter_class => "gutter", + :code_class => "code" + ) + lexer = ::Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText + formatter.format(lexer.lex(code)) + end + + def render_codehighlighter(code) + h(code).strip + end + + def add_code_tag(code) + code_attributes = [ + "class=\"language-#{@lang.to_s.tr("+", "-")}\"", + "data-lang=\"#{@lang}\"", + ].join(" ") + + output = "
"
+        output += code.chomp
+        output += "
" + + if @opts["tio"] + output += "" + end + + output += "
" + + output + end + end + end +end + +Liquid::Template.register_tag("highlight", Jekyll::Tags::HighlightBlock) -- cgit v1.1