module Snibbets module Highlight class << self def run_command_with_input(*cmd, input: nil, fallback: nil) stdout, _stderr, status = Open3.capture3(*cmd, stdin_data: input) if status.success? stdout elsif fallback.nil? input else run_command_with_input(fallback, input: input, fallback: nil) end end def highlight_pygments(executable, code, syntax, theme) syntax = syntax.nil? || syntax.empty? ? '-g' : "-l #{syntax}" theme = theme.nil? || theme.empty? ? '' : ",style=#{theme}" command = "#{executable} -O full#{theme} #{syntax}" fallback = "#{executable} -O full#{theme} -g" run_command_with_input(command, input: code, fallback: fallback) end def highlight_skylight(executable, code, syntax, theme) theme ||= 'nord' theme_file = if theme =~ %r{^[/~].*?(\.theme)?$} theme = theme.sub(/(\.theme)?$/, '.theme') File.expand_path(theme) else theme = theme.sub(/\.theme$/, '') File.join(__dir__, '..', 'themes', "#{theme}.theme") end theme = if File.exist?(theme_file) "-t #{theme_file} " else '' end return code if syntax.nil? || syntax.empty? || !Lexers.skylight_lexer?(syntax) run_command_with_input("#{executable} #{theme}--syntax #{syntax}", input: code) end def highlight_fences(code, filename, syntax) content = code.dup content.fences.each do |f| rx = Regexp.new(Regexp.escape(f[:code])) syn = Lexers.normalize_lexer(f[:lang] || syntax) highlighted = highlight(f[:code].gsub(/\\k