-
-
Save bitti/016ea088f1e9dfc7120eb5f8c937c2da to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby | |
require 'redcarpet' | |
require 'pygments' | |
require 'erb' | |
input = ARGV[0] && ARGV[0] != "-" && File.open(ARGV[0]) || STDIN | |
output = ARGV[1] && File.open(ARGV[1], "w") || STDOUT | |
cache_dir = File.join(ENV["XDG_CACHE_HOME"] || "#{ENV['HOME']}/.cache", "gfm-render") | |
class RenderWithTaskLists < Redcarpet::Render::HTML | |
def list_item(text, list_type) | |
if text.start_with?("[x]", "[X]") | |
text[0..2] = %(<input type="checkbox" class="task-list-item-checkbox" disabled="" checked="checked">) | |
elsif text.start_with?("[ ]") | |
text[0..2] = %(<input type="checkbox" class="task-list-item-checkbox" disabled="">) | |
end | |
%(<li class="task-list-item">#{text}</li>) | |
end | |
def block_code( code, language ) | |
Pygments.highlight( code, lexer: language ) | |
end | |
end | |
markdown_renderer = Redcarpet::Markdown.new( | |
RenderWithTaskLists, | |
no_intra_emphasis: true, | |
autolink: true, | |
tables: true, | |
fenced_code_blocks: true, | |
lax_spacing: true, | |
# Other options to consider: | |
# | |
# with_toc_data: true, | |
# strikethrough: true, | |
# superscript: true, | |
# underline: true, | |
# highlight: true | |
) | |
html_output = markdown_renderer.render(input.read) | |
name = input.is_a?(File) && File.basename(input) || "<stdin>" | |
gh_markdown_css_filename = File.join(cache_dir, "github-markdown.css") | |
unless File.exist?(gh_markdown_css_filename) | |
require 'net/http' | |
require 'pathname' | |
CSS_URL = 'https://raw.githubusercontent.com/sindresorhus/github-markdown-css/main/github-markdown.css' | |
STDERR.puts "Download #{CSS_URL} and cache to #{gh_markdown_css_filename}" | |
Pathname.new(gh_markdown_css_filename).dirname.mkpath | |
File.open(gh_markdown_css_filename, "w") do |css| | |
css.write(Net::HTTP.get(URI(CSS_URL))) | |
end | |
end | |
gh_markdown_css = File.read(gh_markdown_css_filename) | |
erb = ERB.new(DATA.read) | |
output.write(erb.result) | |
__END__ | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Rendered <%= name %></title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style> | |
<%= gh_markdown_css %> | |
<%= Pygments.css('.highlight', style: 'gruvbox-dark') %> | |
@media (prefers-color-scheme: dark) { | |
body { | |
color: #c9d1d9; | |
background-color: #0d1117; | |
} | |
} | |
@media (prefers-color-scheme: light) { | |
body { | |
color: #24292f; | |
background-color: #ffffff; | |
} | |
} | |
.markdown-body { | |
box-sizing: border-box; | |
min-width: 200px; | |
max-width: 980px; | |
margin: 1 auto; | |
padding: 45px; | |
border: 1px solid #d0d7de; | |
border-radius: 6px; | |
} | |
@media (max-width: 767px) { | |
.markdown-body { | |
padding: 15px; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<article class="markdown-body"> | |
<%= html_output %> | |
</article> | |
</body> | |
</html> |
Pysis868/gfm-render - Revision #5
Moved CSS download check to the beginning so that can completed more quickly with a quick, initial script execution without providing any parameters/files.
Added related CLI option to help facilitate this with a simple program exit to not keep the user's terminal busy, possibly unexpectedly, and another to possibly re-download it later.
Added help text.
Thanks @Pysis868, I'd like to integrate your changes in my version. But I also extended it in a different way by integrating source code rendering via pygments.rb (which is the old way GitHub used to render source code, before they replaced it with a proprietary way).
To make it work this command needs to be added to step 2 above:
$ gem i --user-install pygments.rb -v 3.0.0
(Using the old 3.0.0 version is necessary if you use the default Ruby 2.6 currently included in macOS. If you use a newer Ruby version, you probably can also use the newest pygments.rb gem.)
Setup:
$PATH
and make executable$ chmod +x gfm-render
$ gem i --user-install redcarpet
github-markdown.css
Inspired by