repubmark/lib/repubmark/highlight.rb

86 lines
1.7 KiB
Ruby

# frozen_string_literal: true
module Repubmark
class Highlight
NO_SYNTAX = 'txt'
NO_LINE_NUMBERS = %i[sh_hist].freeze
SYNTAXES = {
certbot: 'ini',
css: 'css',
hjson: nil,
html: 'html',
ini: 'ini',
knockd: nil,
nginx: 'nginx',
openssh: nil,
ruby: 'ruby',
sh_hist: nil,
sysctl: nil,
torrc: nil,
wireguard: 'ini',
yggdrasil: nil, # Hjson
}.freeze
private_class_method :new
def self.call(...) = new(...).call
attr_reader :syntax, :str
def initialize(syntax, str)
self.syntax = syntax
self.str = str
end
def call
Open3.popen2(*cmdline) do |stdin, stdout, wait_thr|
stdin.write str
stdin.close
result = stdout.read.freeze
raise 'Highlight error' unless wait_thr.value.success?
"<pre><code>#{result}</code></pre>\n".freeze
end
end
private
def syntax=(syntax)
return @syntax = nil if syntax.nil?
unless syntax.instance_of? Symbol
raise TypeError, "Expected #{Symbol}, got #{syntax.class}"
end
SYNTAXES.fetch syntax
@syntax = syntax
end
def str=(str)
str = String(str).strip.freeze
raise 'Expected non-empty string' if str.empty?
@str = str
end
def cmdline
@cmdline ||= [
'highlight',
'--stdout',
'--fragment',
'--out-format',
'html',
'--syntax',
SYNTAXES[syntax] || NO_SYNTAX,
].tap do |cmdline|
unless syntax.nil? || NO_LINE_NUMBERS.include?(syntax)
cmdline << '--line-numbers'
end
end.freeze
end
end
end