Skip to content

Commit

Permalink
Merge pull request #102 from joyofrails/feat/inline-phlex-markdown
Browse files Browse the repository at this point in the history
Reimplment phlex-markdown as markdown base component
  • Loading branch information
rossta authored May 4, 2024
2 parents 4853b17 + d399646 commit f975598
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ gem "inline_svg" # Embed SVGs in Rails views and style them with CSS [https://gi
gem "rouge", group: [:default, :wasm] # Pure Ruby syntaix highlighter [https://github.com/rouge-ruby/rouge
gem "sitepress-rails", group: [:default, :wasm] # Static site generator for Rails [https://sitepress.cc/getting-started/rails]
gem "phlex-rails", group: [:default, :wasm] # An object-oriented alternative to ActionView for Ruby on Rails. [https://github.com/phlex-ruby/phlex-rails]
gem "phlex-markdown", github: "phlex-ruby/phlex-markdown", group: [:default, :wasm] # A markdown component for Phlex [https://github.com/phlex-ruby/phlex-markdown]
gem "markly"

gem "bootsnap", require: false # Reduces boot times through caching; required in config/boot.rb [https://github.com/Shopify/bootsnap]

Expand Down
10 changes: 1 addition & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
GIT
remote: https://github.com/phlex-ruby/phlex-markdown.git
revision: ee1e2763fc842563577003a269982cfc4ac79006
specs:
phlex-markdown (0.3.0)
markly (~> 0.7)
phlex (>= 0.5)

GIT
remote: https://github.com/rubycdp/cuprite
revision: 9e2788fac70a9d250364ced47a50b77e18fe31a5
Expand Down Expand Up @@ -542,8 +534,8 @@ DEPENDENCIES
letter_opener
litestream
mail_interceptor
markly
mission_control-jobs
phlex-markdown!
phlex-rails
puma (>= 5.0)
rack-mini-profiler
Expand Down
93 changes: 90 additions & 3 deletions app/views/components/markdown/base.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,99 @@
class Markdown::Base < Phlex::Markdown
# frozen_string_literal: true

require "phlex"
require "markly"

class Markdown::Base < Phlex::HTML
def initialize(content, flags: Markly::DEFAULT)
super(content)
@content = content
@flags = flags
end

attr_reader :flags
def template
visit(doc)
end

private

def doc
Markly.parse(@content, flags: @flags)
end

def visit(node)
return if node.nil?

case node.type
in :document
visit_children(node)
in :softbreak
whitespace
visit_children(node)
in :text
plain(node.string_content)
in :header
case node.header_level
in 1 then h1 { visit_children(node) }
in 2 then h2 { visit_children(node) }
in 3 then h3 { visit_children(node) }
in 4 then h4 { visit_children(node) }
in 5 then h5 { visit_children(node) }
in 6 then h6 { visit_children(node) }
end
in :paragraph
grandparent = node.parent&.parent

if grandparent&.type == :list && grandparent&.list_tight
visit_children(node)
else
p { visit_children(node) }
end
in :link
a(href: node.url, title: node.title) { visit_children(node) }
in :image
img(
src: node.url,
alt: node.each.first.string_content,
title: node.title
)
in :emph
em { visit_children(node) }
in :strong
strong { visit_children(node) }
in :list
case node.list_type
in :ordered_list then ol { visit_children(node) }
in :bullet_list then ul { visit_children(node) }
end
in :list_item
li { visit_children(node) }
in :code
inline_code do |**attributes|
code(**attributes) { plain(node.string_content) }
end
in :code_block
code_block(node.string_content, node.fence_info) do |**attributes|
pre(**attributes) do
code(class: "language-#{node.fence_info}") do
plain(node.string_content)
end
end
end
in :hrule
hr
in :blockquote
blockquote { visit_children(node) }
end
end

def inline_code(**attributes)
yield(**attributes)
end

def code_block(code, language, **attributes)
yield(**attributes)
end

def visit_children(node)
node.each { |c| visit(c) }
end
end
1 change: 0 additions & 1 deletion config/application_wasm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
require "flipper"
require "sitepress-rails"
require "phlex-rails"
require "phlex/markdown"
require "inline_svg"

module Joy
Expand Down
109 changes: 109 additions & 0 deletions spec/views/components/markdown/base_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Markdown::Base do
it "supports multiple headings" do
output = md <<~MD
# 1
## 2
### 3
#### 4
##### 5
###### 6
MD

expect(output).to be ==
"<h1>1</h1><h2>2</h2><h3>3</h3><h4>4</h4><h5>5</h5><h6>6</h6>"
end

it "supports ordered lists" do
output = md <<~MD
1. One
2. Two
3. Three
MD

expect(output).to be ==
"<ol><li>One</li><li>Two</li><li>Three</li></ol>"
end

it "supports unordered lists" do
output = md <<~MD
- One
- Two
- Three
MD

expect(output).to be ==
"<ul><li>One</li><li>Two</li><li>Three</li></ul>"
end

it "supports inline code" do
output = md "Some `code` here"
expect(output).to be == "<p>Some <code>code</code> here</p>"
end

it "supports block code" do
output = md <<~MD
```ruby
def foo
bar
end
```
MD

expect(output).to be ==
%(<pre><code class="language-ruby">def foo\n bar\nend\n</code></pre>)
end

it "supports paragraphs" do
output = md "A\n\nB"
expect(output).to be == "<p>A</p><p>B</p>"
end

it "supports links" do
output = md "[Hello](world 'title')"
expect(output).to be == %(<p><a href="world" title="title">Hello</a></p>)
end

it "supports emphasis" do
output = md "*Hello*"
expect(output).to be == "<p><em>Hello</em></p>"
end

it "supports strong" do
output = md "**Hello**"
expect(output).to be == "<p><strong>Hello</strong></p>"
end

it "supports blockquotes" do
output = md "> Hello"
expect(output).to be == "<blockquote><p>Hello</p></blockquote>"
end

it "supports horizontal rules" do
output = md "---"
expect(output).to be == "<hr>"
end

it "supports images" do
output = md "![alt](src 'title')"
expect(output).to be == %(<p><img src="src" alt="alt" title="title"></p>)
end

it "supports softbreaks in content as spaces" do
output = md <<~MD
One
Two
Three
MD

expect(output).to be == "<p>One Two</p><p>Three</p>"
end

def md(content)
Markdown::Base.new(content).call
end
end

0 comments on commit f975598

Please sign in to comment.