parent
880655b388
commit
4af02c8a48
6 changed files with 118 additions and 0 deletions
55
app/liquid_tags/kotlin_tag.rb
Normal file
55
app/liquid_tags/kotlin_tag.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
class KotlinTag < LiquidTagBase
|
||||
PARTIAL = "liquids/kotlin".freeze
|
||||
|
||||
def initialize(tag_name, link, tokens)
|
||||
super
|
||||
stripped_link = ActionController::Base.helpers.strip_tags(link)
|
||||
the_link = stripped_link.split(" ").first
|
||||
@embedded_url = KotlinTag.embedded_url(the_link)
|
||||
end
|
||||
|
||||
def render(_context)
|
||||
ActionController::Base.new.render_to_string(
|
||||
partial: PARTIAL,
|
||||
locals: {
|
||||
url: @embedded_url
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def self.embedded_url(link)
|
||||
"https://play.kotlinlang.org/embed?" + URI.encode_www_form(parse_link(link))
|
||||
end
|
||||
|
||||
def self.parse_link(link)
|
||||
begin
|
||||
url = URI(link)
|
||||
rescue
|
||||
raise_error
|
||||
end
|
||||
hostname_ok = url.hostname == "pl.kotl.in"
|
||||
short = url.path.delete("/")
|
||||
raise_error unless hostname_ok && valid_param?(short)
|
||||
parse_params(url, short)
|
||||
end
|
||||
|
||||
def self.parse_params(url, short)
|
||||
query = url.query.nil? ? [] : URI.decode_www_form(url.query)
|
||||
result = { short: short }
|
||||
%i[from to theme readOnly].each do |param|
|
||||
value = query.assoc(param.id2name)&.last
|
||||
result[param] = valid_param?(value) ? value : ""
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def self.valid_param?(value)
|
||||
!value&.match(/^[a-zA-Z0-9]+$/)&.nil?
|
||||
end
|
||||
|
||||
def raise_error
|
||||
raise StandardError, "Invalid Kotlin Playground URL"
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("kotlin", KotlinTag)
|
||||
6
app/views/liquids/_kotlin.html.erb
Normal file
6
app/views/liquids/_kotlin.html.erb
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<iframe
|
||||
src="<%= url %>"
|
||||
allowtransparency="true"
|
||||
scrolling="no"
|
||||
frameborder="0"
|
||||
></iframe>
|
||||
|
|
@ -178,6 +178,10 @@
|
|||
<code>{% codepen https://codepen.io/twhite96/pen/XKqrJX default-tab=js,result %}</code>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3><strong>Kotlin Playground</strong></h3>
|
||||
<p>To create a runnable kotlin snippet, create a Kotlin Snippet at <a href="https://play.kotlinlang.org">https://play.kotlinlang.org</a></p>
|
||||
<p>Go to <code>Share</code> dialog and copy the full <code>link</code> from the <code>Medium</code> tab. Use it as follows:</p>
|
||||
<code>{% kotlin https://pl.kotl.in/owreUFFUG?theme=darcula&from=3&to=6&readOnly=true %}</code>
|
||||
<h3><strong>RunKit Embed</strong></h3>
|
||||
<p>Put executable code within a runkit liquid block, as follows:</p>
|
||||
<pre>{% runkit<br>// hidden setup JavaScript code goes in this preamble area<br>const hiddenVar = 42<br>%}<br>// visible, reader-editable JavaScript code goes here<br>console.log(hiddenVar)<br>{% endrunkit %} <br></pre>
|
||||
|
|
|
|||
|
|
@ -40,4 +40,5 @@ Here is a bunch of liquid tags supported on DEV:
|
|||
{% soundcloud https://soundcloud.com/user-261265215/dev-to-review-episode-1 %}
|
||||
{% spotify spotify:episode:5V4XZWqZQJvbddd31n56mf %}
|
||||
{% blogcast 1234 %}
|
||||
{% kotlin https://pl.kotl.in/owreUFFUG %}
|
||||
```
|
||||
|
|
|
|||
46
spec/liquid_tags/kotlin_tag_spec.rb
Normal file
46
spec/liquid_tags/kotlin_tag_spec.rb
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe KotlinTag, type: :liquid_template do
|
||||
describe "#link" do
|
||||
input = "https://pl.kotl.in/owreUFFUG?theme=darcula&from=3&to=6&readOnly=true"
|
||||
expected = "https://play.kotlinlang.org/embed?short=owreUFFUG&from=3&to=6&theme=darcula&readOnly=true"
|
||||
|
||||
def generate_new_liquid(link)
|
||||
Liquid::Template.register_tag("kotlin", KotlinTag)
|
||||
Liquid::Template.parse("{% kotlin #{link} %}")
|
||||
end
|
||||
|
||||
it "accepts only Kotlin Playground links" do
|
||||
badurl = "https://example.com"
|
||||
expect do
|
||||
generate_new_liquid(badurl)
|
||||
end.to raise_error(StandardError)
|
||||
|
||||
badurl = "not even an URL"
|
||||
expect do
|
||||
generate_new_liquid(badurl)
|
||||
end.to raise_error(StandardError)
|
||||
end
|
||||
|
||||
def check(url, expected)
|
||||
expect(KotlinTag.parse_link(url)).to eq(expected)
|
||||
end
|
||||
|
||||
it "parses URL correctly" do
|
||||
check("https://pl.kotl.in/owreUFFUG", from: nil, readOnly: nil, short: "owreUFFUG", theme: nil, to: nil)
|
||||
check("https://pl.kotl.in/owreUFFUG?theme=dracula&from=3&to=6&readOnly=true", from: "3", readOnly: "true", short: "owreUFFUG", theme: "dracula", to: "6")
|
||||
check("https://pl.kotl.in/owreUFFUG?theme=dracula&readOnly=true", from: nil, readOnly: "true", short: "owreUFFUG", theme: "dracula", to: nil)
|
||||
check("https://pl.kotl.in/owreUFFUG?from=3&to=6", from: "3", readOnly: nil, short: "owreUFFUG", theme: nil, to: "6")
|
||||
end
|
||||
|
||||
it "produces a correct final URL" do
|
||||
expect(KotlinTag.embedded_url(input)).to eq(expected)
|
||||
end
|
||||
|
||||
it "renders correctly a Kotlin Playground link" do
|
||||
liquid = generate_new_liquid(input)
|
||||
rendered_kotlin_iframe = liquid.render
|
||||
Approvals.verify(rendered_kotlin_iframe, name: "kotlin_liquid_tag", format: :html)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<iframe src="https://play.kotlinlang.org/embed?short=owreUFFUG&from&to&theme=darcula&readOnly" allowtransparency="true" scrolling="no" frameborder="0"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue