blog-static/convert.rb
Danila Fedorin c197a45540 Port over the HTML conversion script to execute JS
Signed-off-by: Danila Fedorin <danila.fedorin@gmail.com>
2024-05-23 21:03:03 -07:00

49 lines
1.3 KiB
Ruby

require "execjs"
require "nokogiri"
require "net/http"
require "json"
require "cgi"
class KatexRenderer
def initialize(source)
@context = ExecJS.compile(source)
@inline_cache = {}
@display_cache = {}
end
def render(display, string)
cache = display ? @display_cache : @inline_cache
comment = display ? "display" : string
string = CGI.unescapeHTML string
cache.fetch(string) do
puts " Rendering #{comment}"
options = { "throwOnError" => false, "displayMode" => display }
cache[string] = @context.call("katex.renderToString", string, options)
end
end
def substitute(content)
rendered = content.gsub /\\\(((?:[^\\]|\\[^\)])*)\\\)/ do |match|
render(false, $~[1])
end
rendered = rendered.gsub /\$\$((?:[^\$]|$[^\$])*)\$\$/ do |match|
render(true, $~[1])
end
return rendered
end
end
ExecJS.runtime = ExecJS::Runtimes::Duktape
renderer = KatexRenderer.new(Net::HTTP.get(URI("https://static.danilafe.com/katex/katex.min.js")))
files = ARGV[0..-1]
files.each do |file|
puts "Rendering file: #{file}"
document = Nokogiri::HTML.parse(File.open(file))
document.search('//*[not(ancestor-or-self::code or ancestor-or-self::script)]/text()').each do |t|
t.replace(renderer.substitute(t.content))
end
File.write(file, document.to_html(encoding: 'UTF-8'))
end