-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reimplement phlex-markdown as markdown base component
- Loading branch information
Showing
5 changed files
with
201 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |