Skip to content

Commit

Permalink
Improve Markdown rendering
Browse files Browse the repository at this point in the history
- Introduce `MarkdownRenderer` class (inspired by https://railsinspire.com/samples/16/files/64)

- Syntax highlight code blocks in markdown

- Allow `UI::CodeBlock` to be rendered in any language
  • Loading branch information
marcoroth committed Aug 27, 2023
1 parent a42c6a3 commit 1a775d4
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 47 deletions.
6 changes: 2 additions & 4 deletions app/components/ui/code_block.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<pre class="rouge border border-gray-300 rounded overflow-scroll">
<%== formatter.format(lexer.lex(content)) %>
</pre>
<pre id="<%= id %>" class="rouge border border-gray-300 rounded overflow-scroll px-4 py-2"><%== formatter.format(lexer.lex(content)) %></pre>

<style type="text/css">
<%= Rouge::Themes::Github.render(scope: 'pre.rouge') %>
<%= Rouge::Themes::Github.render(scope: "pre##{id}.rouge") %>
</style>
8 changes: 7 additions & 1 deletion app/components/ui/code_block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ def formatter
end

def lexer
@lexer ||= Rouge::Lexers::Ruby.new
"Rouge::Lexers::#{@language.camelize}".constantize.new
rescue StandardError
Rouge::Lexers::PlainText.new
end

def id
@id ||= "code-block-#{rand(10_000)}"
end
end
7 changes: 7 additions & 0 deletions app/helpers/markdown_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module MarkdownHelper
def render_markdown(content)
MarkdownRenderer.new(sanitize(content)).render
end
end
26 changes: 11 additions & 15 deletions app/models/gem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,6 @@ def guide_files
metadata.files.select { |file| (file.include?("guide/") || file.include?("guides/")) && file.end_with?(".md") }
end

def content_for_markdown(file)
file = "#{file}.md"

if markdown_files.include?(file)
sanitize(File.read("#{unpack_data_path}/#{file}"))
else
%(File "#{file}" not found)
end
end

def rbs_files
metadata.files.select { |file| file.end_with?(".rbs") }
end
Expand All @@ -201,18 +191,24 @@ def readme
markdown_files.find { |file| file.downcase.include?("readme") } || markdown_files.first
end

def sanitize(content)
Rails::HTML5::FullSanitizer.new.sanitize(content)
end

def readme_content
if readme
sanitize(File.read("#{unpack_data_path}/#{readme}"))
File.read("#{unpack_data_path}/#{readme}")
else
"No README"
end
end

def content_for_markdown(file)
file = "#{file}.md"

if markdown_files.include?(file)
File.read("#{unpack_data_path}/#{file}")
else
%(File "#{file}" not found)
end
end

def download_path
"tmp/gems/#{name}".tap do |path|
FileUtils.mkdir_p(path)
Expand Down
58 changes: 58 additions & 0 deletions app/models/markdown_renderer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# frozen_string_literal: true

class MarkdownRenderer
class DefaultRenderer < Redcarpet::Render::HTML
include Redcarpet::Render::SmartyPants

def block_code(code, language)
ApplicationController.render(UI::CodeBlock.new(language:).with_content(code), layout: false)
end
end

def initialize(content)
@content = content
end

def render
return "" if content.blank?

renderer.render(content)
end

private

attr_reader :content

def renderer
Redcarpet::Markdown.new(
DefaultRenderer.new(**markdown_settings),
renderer_settings,
)
end

def markdown_settings
{
hard_wrap: true,
no_images: false,
no_links: false,
with_toc_data: false,
}
end

def renderer_settings
{
autolink: true,
disable_indented_code_blocks: true,
fenced_code_blocks: true,
footnotes: true,
gh_blockcode: true,
highlight: true,
lax_spacing: true,
no_intra_emphasis: true,
strikethrough: true,
superscript: true,
tables: true,
underline: true,
}
end
end
10 changes: 1 addition & 9 deletions app/views/gems/docs/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
</div>

<div class="prose max-w-full border border-gray-200 rounded p-8 mt-6">
<% markdown = Redcarpet::Markdown.new(
Redcarpet::Render::HTML,
autolink: true,
tables: true,
fenced_code_blocks: true,
lax_spacing: true
) %>
<%== markdown.render(@gem.content_for_markdown(params[:id])) %>
<%== render_markdown(@gem.content_for_markdown(params[:id])) %>
</div>
<% end %>
10 changes: 1 addition & 9 deletions app/views/gems/guides/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
</div>

<div class="prose max-w-full border border-gray-200 rounded p-8 mt-6">
<% markdown = Redcarpet::Markdown.new(
Redcarpet::Render::HTML,
autolink: true,
tables: true,
fenced_code_blocks: true,
lax_spacing: true
) %>
<%== markdown.render(@gem.content_for_markdown(params[:id])) %>
<%== render_markdown(@gem.content_for_markdown(params[:id])) %>
</div>
<% end %>
10 changes: 1 addition & 9 deletions app/views/gems/pages/readme.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@
<%= render Gems::Wrapper.new(gem: @gem, modules: @gem.top_level_modules, classes: @gem.top_level_classes, class_methods: @gem.class_methods, instance_methods: @gem.instance_methods) do %>
<div class="prose max-w-full border border-gray-200 rounded p-8 mt-6">
<% markdown = Redcarpet::Markdown.new(
Redcarpet::Render::HTML,
autolink: true,
tables: true,
fenced_code_blocks: true,
lax_spacing: true
) %>
<%== markdown.render(@gem.readme_content) %>
<%== render_markdown(@gem.readme_content) %>
</div>
<% end %>

0 comments on commit 1a775d4

Please sign in to comment.