Skip to content

Commit

Permalink
Basic ragelpen working. Next up a run simulator.
Browse files Browse the repository at this point in the history
  • Loading branch information
ijcd committed Nov 14, 2015
1 parent 431f5c2 commit e73899e
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 30 deletions.
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ gem 'volt-mailer', '~> 0.1.1'
# click to edit text
gem 'volt-editable_text', path: 'gems/volt-editable_text'

# code highlighting
gem 'volt-code_highlight'

gem 'oga'

# Use rbnacl for message bus encrpytion
# (optional, if you don't need encryption, disable in app.rb and remove)
#
Expand Down
11 changes: 11 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ PATH
GEM
remote: https://rubygems.org/
specs:
ansi (1.5.0)
archive-zip (0.7.0)
io-like (~> 0.3.0)
ast (2.1.0)
bcrypt (3.1.10)
bson (3.2.6)
byebug (4.0.5)
Expand Down Expand Up @@ -70,6 +72,9 @@ GEM
multi_json (1.11.2)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
oga (1.3.1)
ast
ruby-ll (~> 2.1)
opal (0.8.1)
hike (~> 1.2)
sourcemap (~> 0.1.0)
Expand Down Expand Up @@ -116,6 +121,9 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.2)
ruby-ll (2.1.2)
ansi
ast
rubyzip (1.1.7)
sass (3.4.19)
selenium-webdriver (2.47.1)
Expand Down Expand Up @@ -153,6 +161,7 @@ GEM
thor (~> 0.19.0)
volt-bootstrap (0.1.0)
volt-bootstrap_jumbotron_theme (0.1.0)
volt-code_highlight (0.2.0)
volt-fields (0.1.3)
volt-mailer (0.1.2)
pony (~> 1.11)
Expand All @@ -178,6 +187,7 @@ DEPENDENCIES
csso-rails (~> 0.3.4)
image_optim
image_optim_pack
oga
opal-rspec (~> 0.4.2)
poltergeist (~> 1.6.0)
pry-byebug
Expand All @@ -190,6 +200,7 @@ DEPENDENCIES
volt (= 0.9.6)
volt-bootstrap (~> 0.1.0)
volt-bootstrap_jumbotron_theme (~> 0.1.0)
volt-code_highlight
volt-editable_text!
volt-mailer (~> 0.1.1)
volt-mongo (~> 0.1.0)
Expand Down
3 changes: 3 additions & 0 deletions app/main/config/dependencies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@

# editable text
component 'editable_text'

# code highlight
component 'code_highlight'
64 changes: 40 additions & 24 deletions app/main/controllers/main_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class MainController < Volt::ModelController
model :store

def index
# Add code for when the index view is loaded
select_pen(params._index || 0)
end

def about
Expand All @@ -18,38 +18,54 @@ def add_pen
params._index = _pens.array.length - 1
end

def remove_pen(pen)
def remove_pen(pen, index)
pen.destroy
if params._index > _pens.array.length - 1
params._index = _pens.array.length - 1
new_index = (index <= current_index) ? (current_index - 1) : current_index
if new_index >= 0
params._index = new_index
else
params._index = nil
end
end

def set_max_index

def select_pen(index)
params._index = index
current_pen.then do |pen|
page._ragel_input = pen._ragel_content
end
end

def current_index
params._index.to_i
def update_pen(ragel_input)
current_pen.then do |pen|
RagelTasks.run_ragel(pen.id, ragel_input).then do |result|
puts "Result: #{result}"
end.fail do |error|
puts "Error: #{error}"
end
end
end

def current_pen
_pens[current_index]
end
def current_index
params._index.to_i
end

private
def current_pen
_pens[current_index] || Pen.new_index
end

# The main template contains a #template binding that shows another
# template. This is the path to that template. It may change based
# on the params._component, params._controller, and params._action values.
def main_path
"#{params._component || 'main'}/#{params._controller || 'main'}/#{params._action || 'index'}"
end
private

# Determine if the current nav component is the active one by looking
# at the first part of the url against the href attribute.
def active_tab?
url.path.split('/')[1] == attrs.href.split('/')[1]
end
# The main template contains a #template binding that shows another
# template. This is the path to that template. It may change based
# on the params._component, params._controller, and params._action values.
def main_path
"#{params._component || 'main'}/#{params._controller || 'main'}/#{params._action || 'index'}"
end

# Determine if the current nav component is the active one by looking
# at the first part of the url against the href attribute.
def active_tab?
url.path.split('/')[1] == attrs.href.split('/')[1]
end
end
end
end
12 changes: 12 additions & 0 deletions app/main/lib/svg_wrapper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'oga'

class SvgWrapper
def initialize(string)
@root = Oga.parse_xml(string).at_xpath('/svg')
@root.attributes.reject!{|a| ["xmlns", "xlink"].include?(a.name) }
end

def as_embed
@root.to_xml
end
end
5 changes: 5 additions & 0 deletions app/main/tasks/logging_tasks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class LoggingTasks < Volt::Task
def log(message)
puts message
end
end
82 changes: 82 additions & 0 deletions app/main/tasks/ragel_tasks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
require 'open3'
require 'main/lib/svg_wrapper'

class RagelTasks < Volt::Task
def run_ragel(pen_id, ragel_input)

# lookup the pen
store._pens.find(id: pen_id).first.then do |pen|

# clear any errors
pen._error = ""

# set the ragel_content
pen._ragel_content = ragel_input

# setup tempdir
Dir.mktmpdir do |dir|

# create the ragel file
ragel_file = create_ragel(dir, pen._ragel_content)

# run ragel -R to create the rb file and save the output
ruby_file, err, status = create_ruby(dir, ragel_file)
return build_error(pen, err) unless status.success?
pen._ruby_content = File.read(ruby_file)

# # run ragel -V to create the dot file
dot_file, err = create_dot(dir, ragel_file)
return build_error(pen, err) unless status.success?
pen._dot_content = File.read(dot_file)

# convert to png (or svg)
svg_file, err = create_svg(dir, dot_file)
return build_error(pen, err) unless status.success?
pen._svg_content = SvgWrapper.new(File.read(svg_file)).as_embed

# return png/svg or link to the same
"ok"
end
end
end

protected

def create_ragel(dir, content)
File.join(dir, "input.rl").tap do |fn_output|
File.open(fn_output, 'w') do |file|
file.write(content)
end
end
end

def create_ruby(dir, fn_input)
File.join(dir, "output.rb").tap do |fn_output|
out, err, status = Open3.capture3("ragel -R #{fn_input} -o #{fn_output}")
return [fn_output, err, status]
end
end

def create_dot(dir, fn_input)
File.join(dir, "output.dot").tap do |fn_output|
out, err, status = Open3.capture3("ragel -V #{fn_input} -o #{fn_output}")
return [fn_output, err, status]
end
end

def create_svg(dir, fn_input)
File.join(dir, "output.svg").tap do |fn_output|
out, err, status = Open3.capture3("dot -Tsvg #{fn_input} -o #{fn_output}")
return [fn_output, err, status]
end
end

def build_error(pen, err)
pen._error = err
pen._ruby_content = ''
pen._dot_content = ''
pen._svg_content = ''
Promise.error(err)
end

end
35 changes: 29 additions & 6 deletions app/main/views/main/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,47 @@ <h1>Ragel Pens</h1>
<table class="table">
{{ _pens.each_with_index do |pen, index| }}
<tr
e-click="params._index = index"
e-click="select_pen(index)"
class="{{ if current_index == index }}selected{{ end }}"
>
<td>{{ pen._name }}</td>
<td><button e-click="remove_pen(pen)">X</button></td>
<td><button e-click="remove_pen(pen, index)">X</button></td>
</tr>
{{ end }}
</table>

<button e-click="add_pen">Add Pen</button>
<button e-click="update_pen(page._ragel_input)">Run Pen</button>

<input id="autoupdate" type="checkbox" checked="{{ page._autoupdate_pen }}" />
<label for="autoupdate">autoupdate</label>

{{ if current_pen }}
<h1><:editable_text value="{{ current_pen._name}}" /></h1>

<textarea>{{ current_pen._content }}</textarea>
<textarea e-input="update_pen(page._ragel_input)">{{ page._ragel_input }}</textarea>

{{ raw current_pen._svg_content }}

<hr>

<pre style="color: red">{{ current_pen._error }}</pre>

<:code_highlight>
<pre>{{ current_pen._ragel_content }}</pre>
</:code_highlight>

<:code_highlight language="ruby">
<pre>{{ current_pen._ruby_content }}</pre>
</:code_highlight>

<pre>
{{ current_pen._content }}
</pre>
<:code_highlight>
<pre>{{ current_pen._dot_content }}</pre>
</:code_highlight>

<:code_highlight language="xml">
<pre>{{ current_pen._svg_content }}</pre>
</:code_highlight>

{{ end }}

0 comments on commit e73899e

Please sign in to comment.