flammarion 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.md +12 -4
- data/lib/flammarion.rb +12 -133
- data/lib/flammarion/about.rb +2 -0
- data/lib/flammarion/engraving.rb +171 -0
- data/lib/flammarion/pane.rb +1 -0
- data/lib/flammarion/revelator.rb +20 -20
- data/lib/flammarion/server.rb +1 -0
- data/lib/flammarion/version.rb +1 -1
- data/lib/flammarion/writeable.rb +71 -4
- data/lib/html/build/javascripts/actions.js +11 -1
- data/lib/html/build/javascripts/all.js +12 -2
- data/lib/html/build/javascripts/input.js +11 -1
- data/lib/html/build/javascripts/map.js +11 -1
- data/lib/html/build/javascripts/plot.js +1 -1
- data/lib/html/build/javascripts/websocket.js +11 -1
- data/lib/html/source/javascripts/plot.coffee +1 -1
- data/lib/html/source/javascripts/websocket.coffee +2 -0
- metadata +2 -1
data/Readme.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/flammarion.svg)](https://badge.fury.io/rb/flammarion)
|
4
4
|
|
5
|
+
* [Source](https://github.com/zach-capalbo/flammarion)
|
6
|
+
* [Documentation](http://zach-capalbo.github.io/flammarion/doc/)
|
7
|
+
|
5
8
|
## Overview
|
6
9
|
|
7
10
|
Flammarion is an easy-to-use library for displaying information that you might
|
@@ -13,8 +16,11 @@ without going through too much trouble.
|
|
13
16
|
|
14
17
|
## Installation
|
15
18
|
|
16
|
-
First you need to install [electron](http://electron.atom.io/)
|
17
|
-
and make sure it's in your path.
|
19
|
+
First, you need to install [electron](http://electron.atom.io/) or [chrome](http://www.google.com/chrome)
|
20
|
+
and make sure it's in your path. (*Note:* On Windows, currently only chrome
|
21
|
+
works, but you don't need to worry about putting it in your path.)
|
22
|
+
|
23
|
+
Then you can install the gem:
|
18
24
|
|
19
25
|
```
|
20
26
|
gem install flammarion
|
@@ -70,7 +76,9 @@ f.button("Click Here!!!") {f.puts "You clicked the button!"}
|
|
70
76
|
f.input("Placeholder > ") {|msg| f.puts "You wrote: #{msg['text'].light_magenta}"}
|
71
77
|
```
|
72
78
|
|
73
|
-
The (_almost_) full [api documetaion](http://zach-capalbo.github.io/flammarion/doc/)
|
79
|
+
The (_almost_) full [api documetaion](http://zach-capalbo.github.io/flammarion/doc/)
|
80
|
+
is available at <http://zach-capalbo.github.io/flammarion/doc/>. See especially
|
81
|
+
the [Writeable Module](http://zach-capalbo.github.io/flammarion/doc/Flammarion/Writeable.html)
|
74
82
|
|
75
83
|
## Screenshots / Samples
|
76
84
|
|
@@ -148,7 +156,7 @@ f.pane("sidebar").pane("side2").puts Faker::Hipster.paragraph.green
|
|
148
156
|
|
149
157
|
## Examples
|
150
158
|
|
151
|
-
There are a number of useful examples in the [examples directory.](https://github.com/zach-capalbo/flammarion)
|
159
|
+
There are a number of useful examples in the [examples directory.](https://github.com/zach-capalbo/flammarion/tree/master/examples)
|
152
160
|
|
153
161
|
# Bundled Packages
|
154
162
|
|
data/lib/flammarion.rb
CHANGED
@@ -6,11 +6,14 @@ require 'colorize'
|
|
6
6
|
require 'filewatcher'
|
7
7
|
require 'rbconfig'
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
require '
|
12
|
-
require '
|
13
|
-
require '
|
9
|
+
begin
|
10
|
+
# Optional Requires
|
11
|
+
require 'sass'
|
12
|
+
require 'slim'
|
13
|
+
require 'coffee-script'
|
14
|
+
require 'redcarpet'
|
15
|
+
rescue LoadError
|
16
|
+
end
|
14
17
|
|
15
18
|
require_relative 'flammarion/writeable.rb'
|
16
19
|
require_relative 'flammarion/pane.rb'
|
@@ -18,134 +21,10 @@ require_relative 'flammarion/server.rb'
|
|
18
21
|
require_relative 'flammarion/version.rb'
|
19
22
|
require_relative 'flammarion/revelator.rb'
|
20
23
|
require_relative 'flammarion/about.rb'
|
24
|
+
require_relative 'flammarion/engraving.rb'
|
21
25
|
|
26
|
+
# This is the main namespace for Flammarion.
|
27
|
+
# @see Engraving
|
28
|
+
# @see Writeable
|
22
29
|
module Flammarion
|
23
|
-
class Engraving
|
24
|
-
include Revelator
|
25
|
-
attr_reader :chrome
|
26
|
-
attr_accessor :callbacks, :sockets, :on_disconnect, :on_connect, :actions
|
27
|
-
include Writeable
|
28
|
-
|
29
|
-
# Creates a new Engraving (i.e., a new display window)
|
30
|
-
# @option options [Proc] :on_connect Called when the display window is
|
31
|
-
# connected (i.e., displayed)
|
32
|
-
# @option options [Proc] :on_disconnect Called when the display windows is
|
33
|
-
# disconnected (i.e., closed)
|
34
|
-
def initialize(options = {})
|
35
|
-
@chrome = OpenStruct.new
|
36
|
-
@sockets = []
|
37
|
-
@actions = {}
|
38
|
-
@engraving = self
|
39
|
-
@pane_name = "default"
|
40
|
-
@on_connect = options[:on_connect]
|
41
|
-
@on_disconnect = options[:on_disconnect]
|
42
|
-
@exit_on_disconnect = options.fetch(:exit_on_disconnect, false)
|
43
|
-
|
44
|
-
start_server
|
45
|
-
@window_id = @@server.register_window(self)
|
46
|
-
open_a_window unless options[:no_chrome]
|
47
|
-
@callbacks = {}
|
48
|
-
wait_for_a_connection unless options[:no_wait]
|
49
|
-
|
50
|
-
at_exit {close} if options.fetch(:close_on_exit, false)
|
51
|
-
end
|
52
|
-
|
53
|
-
def disconnect(ws)
|
54
|
-
@sockets.delete ws
|
55
|
-
exit 0 if @exit_on_disconnect
|
56
|
-
@on_disconnect.call if @on_disconnect
|
57
|
-
end
|
58
|
-
|
59
|
-
def wait_until_closed
|
60
|
-
sleep 1 until @sockets.empty?
|
61
|
-
end
|
62
|
-
|
63
|
-
def process_message(msg)
|
64
|
-
@last_msg = msg
|
65
|
-
m = {}
|
66
|
-
begin
|
67
|
-
m = JSON.parse(msg)
|
68
|
-
rescue JSON::ParserError
|
69
|
-
log "Invalid JSON String"
|
70
|
-
return
|
71
|
-
end
|
72
|
-
|
73
|
-
case m["action"]
|
74
|
-
when 'callback'
|
75
|
-
callback = @callbacks[m['id']]
|
76
|
-
unless callback.nil?
|
77
|
-
if callback.arity == 1
|
78
|
-
callback.call(m)
|
79
|
-
else
|
80
|
-
callback.call
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
@actions[m["action"]].call(m) if @actions.include?(m["action"])
|
85
|
-
end
|
86
|
-
|
87
|
-
def make_id
|
88
|
-
@id ||= 0
|
89
|
-
@id += 1
|
90
|
-
"i#{@id}"
|
91
|
-
end
|
92
|
-
|
93
|
-
def start_server
|
94
|
-
@@server ||= Server.new
|
95
|
-
end
|
96
|
-
|
97
|
-
def server; @@server; end;
|
98
|
-
|
99
|
-
def wait_for_a_connection
|
100
|
-
sleep 0.5 while @sockets.empty?
|
101
|
-
end
|
102
|
-
|
103
|
-
def window_open?
|
104
|
-
not @sockets.empty?
|
105
|
-
end
|
106
|
-
|
107
|
-
def send_json(val)
|
108
|
-
if @sockets.empty? then
|
109
|
-
open_a_window
|
110
|
-
wait_for_a_connection
|
111
|
-
end
|
112
|
-
@sockets.each{|ws| ws.send val.to_json}
|
113
|
-
nil
|
114
|
-
end
|
115
|
-
|
116
|
-
def alert(text)
|
117
|
-
send_json(action:'alert', text:text)
|
118
|
-
end
|
119
|
-
|
120
|
-
def orientation=(orientation)
|
121
|
-
raise ArgumentError.new("Orientation must be :horizontal or :vertical") unless [:horizontal, :vertical].include?(orientation)
|
122
|
-
send_json({action:'reorient', orientation:orientation})
|
123
|
-
end
|
124
|
-
|
125
|
-
def title(str)
|
126
|
-
send_json({action:'title', title:str})
|
127
|
-
end
|
128
|
-
|
129
|
-
def layout(file)
|
130
|
-
data = Slim::Template.new(file).render
|
131
|
-
send_json({action:'layout', data:data})
|
132
|
-
end
|
133
|
-
|
134
|
-
def close
|
135
|
-
send_json({action:'close'})
|
136
|
-
end
|
137
|
-
|
138
|
-
def live_reload_layout(file)
|
139
|
-
layout(file); yield if block_given?
|
140
|
-
FileWatcher.new(file).watch {|file| layout(file); yield if block_given? }
|
141
|
-
end
|
142
|
-
|
143
|
-
def get_save_path
|
144
|
-
if Gem.win_platform?
|
145
|
-
`powershell "Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.SaveFileDialog;$f.InitialDirectory='%cd%';$f.Filter='All Files (*.*)|*.*';$f.showHelp=$true;$f.ShowDialog()|Out-Null;$f.FileName"`.strip
|
146
|
-
else
|
147
|
-
`zenity --file-selection --save --confirm-overwrite`.strip
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
30
|
end
|
data/lib/flammarion/about.rb
CHANGED
@@ -0,0 +1,171 @@
|
|
1
|
+
module Flammarion
|
2
|
+
|
3
|
+
# The engraving class represents a window. It contains everything you need to
|
4
|
+
# display on the screen and interacts with a user. An +Engraving+ contains
|
5
|
+
# one or more panes, which are containers for writeable areas. Most of the
|
6
|
+
# power of the panes comes from the +Writeable+ module, which is also included
|
7
|
+
# in +Engraving+ (operating on the default pane) for convenience.
|
8
|
+
# @see Writeable
|
9
|
+
# @note Right now, there is no persistence of Engravings. Once it is closed,
|
10
|
+
# everything is erased, and you'll need to set it up all over again.
|
11
|
+
# @note If you try to display something to a closed window, it will open a new
|
12
|
+
# blank window, and then display that thing.
|
13
|
+
class Engraving
|
14
|
+
include Revelator
|
15
|
+
attr_reader :chrome
|
16
|
+
attr_accessor :callbacks, :sockets, :on_disconnect, :on_connect, :actions
|
17
|
+
include Writeable
|
18
|
+
|
19
|
+
# Creates a new Engraving (i.e., a new display window)
|
20
|
+
# @option options [Proc] :on_connect Called when the display window is
|
21
|
+
# connected (i.e., displayed)
|
22
|
+
# @option options [Proc] :on_disconnect Called when the display windows is
|
23
|
+
# disconnected (i.e., closed)
|
24
|
+
# @option options [Boolean] :exit_on_disconnect (false) Will call +exit+
|
25
|
+
# when the widow is closed if this option is true.
|
26
|
+
# @option options [Boolean] :close_on_exit (false) Will close the window
|
27
|
+
# when the process exits if this is true. Otherwise, it will just stay
|
28
|
+
# around, but not actually be interactive.
|
29
|
+
# @opion options [String] :title The initial title of the engraving. If
|
30
|
+
# empty, a random title will be generated.
|
31
|
+
def initialize(options = {})
|
32
|
+
options = {:title => options} if options.is_a?(String)
|
33
|
+
@chrome = OpenStruct.new
|
34
|
+
@sockets = []
|
35
|
+
@actions = {}
|
36
|
+
@engraving = self
|
37
|
+
@pane_name = "default"
|
38
|
+
@on_connect = options[:on_connect]
|
39
|
+
@on_disconnect = options[:on_disconnect]
|
40
|
+
@exit_on_disconnect = options.fetch(:exit_on_disconnect, false)
|
41
|
+
|
42
|
+
start_server
|
43
|
+
@window_id = @@server.register_window(self)
|
44
|
+
open_a_window(options) unless options[:no_window]
|
45
|
+
@callbacks = {}
|
46
|
+
wait_for_a_connection unless options[:no_wait]
|
47
|
+
|
48
|
+
at_exit {close if window_open?} if options.fetch(:close_on_exit, true)
|
49
|
+
|
50
|
+
title options[:title] if options[:title]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Blocks the current thread until the window has been closed. All user
|
54
|
+
# interactions and callbacks will continue in other threads.
|
55
|
+
def wait_until_closed
|
56
|
+
sleep 1 until @sockets.empty?
|
57
|
+
end
|
58
|
+
|
59
|
+
# Is thie Engraving displayed on the screen.
|
60
|
+
def window_open?
|
61
|
+
not @sockets.empty?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Pops up an alert message containing +text+.
|
65
|
+
def alert(text)
|
66
|
+
send_json(action:'alert', text:text)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Changes the orientation of the panes in this engraving. Options are
|
70
|
+
# - :horizontal
|
71
|
+
# - :vertical
|
72
|
+
def orientation=(orientation)
|
73
|
+
raise ArgumentError.new("Orientation must be :horizontal or :vertical") unless [:horizontal, :vertical].include?(orientation)
|
74
|
+
send_json({action:'reorient', orientation:orientation})
|
75
|
+
end
|
76
|
+
|
77
|
+
# Sets the title of the window
|
78
|
+
def title(str)
|
79
|
+
send_json({action:'title', title:str})
|
80
|
+
end
|
81
|
+
|
82
|
+
# Attempts to close the window.
|
83
|
+
def close
|
84
|
+
send_json({action:'close'})
|
85
|
+
end
|
86
|
+
|
87
|
+
# Opens a native "Save File" Dialog box, prompting the user for a file.
|
88
|
+
def get_save_path
|
89
|
+
if Gem.win_platform?
|
90
|
+
`powershell "Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.SaveFileDialog;$f.InitialDirectory='%cd%';$f.Filter='All Files (*.*)|*.*';$f.showHelp=$true;$f.ShowDialog()|Out-Null;$f.FileName"`.strip
|
91
|
+
else
|
92
|
+
`zenity --file-selection --save --confirm-overwrite`.strip
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Allows you to load a custom layout file. This replaces all html in the
|
97
|
+
# window with a custom slim layout. You probably don't want this unless your
|
98
|
+
# writing a very complex application.
|
99
|
+
def layout(file)
|
100
|
+
data = Slim::Template.new(file).render
|
101
|
+
send_json({action:'layout', data:data})
|
102
|
+
end
|
103
|
+
|
104
|
+
def live_reload_layout(file)
|
105
|
+
layout(file); yield if block_given?
|
106
|
+
FileWatcher.new(file).watch {|file| layout(file); yield if block_given? }
|
107
|
+
end
|
108
|
+
|
109
|
+
# @api private
|
110
|
+
def disconnect(ws)
|
111
|
+
@sockets.delete ws
|
112
|
+
exit 0 if @exit_on_disconnect
|
113
|
+
@on_disconnect.call if @on_disconnect
|
114
|
+
end
|
115
|
+
|
116
|
+
# @api private
|
117
|
+
def process_message(msg)
|
118
|
+
@last_msg = msg
|
119
|
+
m = {}
|
120
|
+
begin
|
121
|
+
m = JSON.parse(msg)
|
122
|
+
rescue JSON::ParserError
|
123
|
+
log "Invalid JSON String"
|
124
|
+
return
|
125
|
+
end
|
126
|
+
|
127
|
+
case m["action"]
|
128
|
+
when 'callback'
|
129
|
+
callback = @callbacks[m['id']]
|
130
|
+
unless callback.nil?
|
131
|
+
if callback.arity == 1
|
132
|
+
callback.call(m)
|
133
|
+
else
|
134
|
+
callback.call
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
@actions[m["action"]].call(m) if @actions.include?(m["action"])
|
139
|
+
end
|
140
|
+
|
141
|
+
# @api private
|
142
|
+
def make_id
|
143
|
+
@id ||= 0
|
144
|
+
@id += 1
|
145
|
+
"i#{@id}"
|
146
|
+
end
|
147
|
+
|
148
|
+
# @api private
|
149
|
+
def start_server
|
150
|
+
@@server ||= Server.new
|
151
|
+
end
|
152
|
+
|
153
|
+
# @api private
|
154
|
+
def server; @@server; end;
|
155
|
+
|
156
|
+
# @api private
|
157
|
+
def wait_for_a_connection
|
158
|
+
sleep 0.5 while @sockets.empty?
|
159
|
+
end
|
160
|
+
|
161
|
+
# @api private
|
162
|
+
def send_json(val)
|
163
|
+
if @sockets.empty? then
|
164
|
+
open_a_window
|
165
|
+
wait_for_a_connection
|
166
|
+
end
|
167
|
+
@sockets.each{|ws| ws.send val.to_json}
|
168
|
+
nil
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
data/lib/flammarion/pane.rb
CHANGED
data/lib/flammarion/revelator.rb
CHANGED
@@ -1,36 +1,24 @@
|
|
1
1
|
module Flammarion
|
2
|
+
# @api private
|
3
|
+
# @todo This all needs a lot of clean up
|
2
4
|
module Revelator
|
3
|
-
def which(cmd)
|
4
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
5
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
6
|
-
exts.each do |ext|
|
7
|
-
exe = File.join(path, "#{cmd}#{ext}")
|
8
|
-
return exe if File.executable?(exe) && !File.directory?(exe)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
return nil
|
12
|
-
end
|
13
|
-
|
14
5
|
CHROME_PATH = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
|
15
|
-
def open_a_window_on_windows
|
6
|
+
def open_a_window_on_windows(options)
|
16
7
|
file_path = File.absolute_path(File.join(File.dirname(__FILE__), ".."))
|
17
8
|
file_path = `cygpath -w '#{file_path}'`.strip if RbConfig::CONFIG["host_os"] == "cygwin"
|
18
9
|
resource = %[file\://#{file_path}/html/build/index.html]
|
19
10
|
chrome_path = CHROME_PATH
|
20
11
|
chrome_path = `cygpath -u '#{CHROME_PATH}'`.strip if RbConfig::CONFIG["host_os"] == "cygwin"
|
21
|
-
spawn(chrome_path, %[--app=#{resource}?path=#{@window_id}&port=#{server.port}])
|
12
|
+
Process.detach(spawn(chrome_path, %[--app=#{resource}?path=#{@window_id}&port=#{server.port}&title="#{options[:title] || "Flammarion%20Engraving"}"]))
|
22
13
|
end
|
23
14
|
|
24
|
-
def open_a_window
|
25
|
-
return open_a_window_on_windows if RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/
|
26
|
-
developmentMode = system("lsof -i:#{4567}", out: '/dev/null')
|
15
|
+
def open_a_window(options = {})
|
16
|
+
return open_a_window_on_windows(options) if RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/
|
17
|
+
developmentMode = system("lsof -i:#{4567}", out: '/dev/null') and File.exist?("#{File.dirname(__FILE__)}/../html/source/index.html.slim")
|
27
18
|
host = "file://#{File.dirname(File.absolute_path(__FILE__))}/../html/build/index.html"
|
28
19
|
host = "http://localhost:4567/" if developmentMode
|
29
20
|
|
30
|
-
|
31
|
-
# File.open("#{data_dir}/First\ Run", "w") {}
|
32
|
-
|
33
|
-
@expect_title = "Flammarion-#{rand.to_s[2..-1]}"
|
21
|
+
@expect_title = options[:title] || "Flammarion-#{rand.to_s[2..-1]}"
|
34
22
|
|
35
23
|
if which('electron') then
|
36
24
|
Process.detach(spawn("electron #{File.dirname(File.absolute_path(__FILE__))}/../../electron '#{host}?path=#{@window_id}&port=#{server.port}&title=#{@expect_title}'"))
|
@@ -44,5 +32,17 @@ module Flammarion
|
|
44
32
|
|
45
33
|
raise StandardError.new("Cannot launch any browser") unless @chrome.in
|
46
34
|
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def which(cmd)
|
38
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
39
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
40
|
+
exts.each do |ext|
|
41
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
42
|
+
return exe if File.executable?(exe) && !File.directory?(exe)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
return nil
|
46
|
+
end
|
47
47
|
end
|
48
48
|
end
|
data/lib/flammarion/server.rb
CHANGED
data/lib/flammarion/version.rb
CHANGED
data/lib/flammarion/writeable.rb
CHANGED
@@ -55,6 +55,13 @@ module Flammarion
|
|
55
55
|
# @note Don't forget to set the :escape_html option to false when including
|
56
56
|
# this string.
|
57
57
|
|
58
|
+
# @!macro [new] add_options
|
59
|
+
# @option options [Boolean] :replace If true, will replace any existing
|
60
|
+
# contents of the writeable area.
|
61
|
+
# @option options [Hash] :style A map of css style attributes and values to
|
62
|
+
# be applied to the element before it is added.
|
63
|
+
|
64
|
+
# @api private
|
58
65
|
def send_json(hash)
|
59
66
|
@engraving.send_json({target: @pane_name}.merge(hash))
|
60
67
|
end
|
@@ -98,7 +105,7 @@ module Flammarion
|
|
98
105
|
|
99
106
|
# Creates a new plot to display single axis data
|
100
107
|
# @param [Array<Number>] values A list of numbers to plot
|
101
|
-
#
|
108
|
+
# @todo finish documenting options
|
102
109
|
# @return [Spectrum] A Spectrum object for manipulation after creation.
|
103
110
|
def plot(values, options = {})
|
104
111
|
id = @engraving.make_id
|
@@ -159,7 +166,7 @@ module Flammarion
|
|
159
166
|
# Creates a string representing a Font Awesome icon.
|
160
167
|
# @macro string_representation
|
161
168
|
# @param name [String] The name of a Font Awesome icon class. See
|
162
|
-
# @see https://fortawesome.github.io/Font-Awesome/icons/
|
169
|
+
# @see https://fortawesome.github.io/Font-Awesome/icons/
|
163
170
|
def icon(name, additional_classes = [])
|
164
171
|
%|<i class="fa fa-#{name} #{additional_classes.collect{|c| "fa-#{c}"}.join(" ")}"></i>|
|
165
172
|
end
|
@@ -259,15 +266,27 @@ module Flammarion
|
|
259
266
|
send_json({action:'replace', text:data, raw:true})
|
260
267
|
end
|
261
268
|
|
262
|
-
|
263
|
-
|
269
|
+
# Runs a script in the engraving window.
|
270
|
+
# @param text [String] The script to run. Lanuage of the script depends on
|
271
|
+
# the options given. Defaults to CoffeeScript
|
272
|
+
# @option options [Boolean] :coffee (true) If true, will compile +text+ from
|
273
|
+
# CoffeeScript to JavaScript. If false, will pass text as plain JavaScript
|
274
|
+
def script(text, options = {})
|
275
|
+
data = options.fetch(:coffee, true) ? CoffeeScript.compile(text) : text
|
264
276
|
send_json({action:'script', data:data}.merge(options))
|
265
277
|
end
|
266
278
|
|
279
|
+
# Sets a CSS styles attribute on the current pane.
|
280
|
+
# @param attribute [String] The css attribute to set. Currently does not
|
281
|
+
# support selectors or anything.
|
282
|
+
# @param value [#to_s] The value to set the attribute to. (Don't forget
|
283
|
+
# units!)
|
267
284
|
def style(attribute, value)
|
268
285
|
send_json({action: 'style', attribute: attribute, value: value})
|
269
286
|
end
|
270
287
|
|
288
|
+
# Will render the given Slim template into the pane
|
289
|
+
# @param file [String] Path to the template file to render
|
271
290
|
def template(file)
|
272
291
|
data = Slim::Template.new(file).render
|
273
292
|
send_json({action:'replace', text:data, raw:true})
|
@@ -277,6 +296,11 @@ module Flammarion
|
|
277
296
|
FileWatcher.new(file).watch {|file| template(file) }
|
278
297
|
end
|
279
298
|
|
299
|
+
# Renders the given markdown text into the pane.
|
300
|
+
# @param text [String] The markdown text to render.
|
301
|
+
# @option options [Hash] :markdown_extensions Additional Redcarpet
|
302
|
+
# extensions to enable.
|
303
|
+
# @macro add_options
|
280
304
|
def markdown(text, options = {})
|
281
305
|
markdown_html = Redcarpet::Markdown.new(Redcarpet::Render::HTML, {
|
282
306
|
tables: true,
|
@@ -288,19 +312,50 @@ module Flammarion
|
|
288
312
|
send_json({action:'markdown', text: markdown_html}.merge(options))
|
289
313
|
end
|
290
314
|
|
315
|
+
# Hides (but doesn't close) the pane. This allows the pane to be written
|
316
|
+
# to without it opening up again.
|
317
|
+
# @see show
|
291
318
|
def hide
|
292
319
|
send_json({action:'hidepane'})
|
293
320
|
end
|
294
321
|
|
322
|
+
# Shows a hidden pane.
|
323
|
+
# @see hide
|
295
324
|
def show
|
296
325
|
send_json({action:'showpane'})
|
297
326
|
end
|
298
327
|
|
328
|
+
# @!macro [new] pane_difference
|
329
|
+
# @note The difference between pane and subpane is that a pane is
|
330
|
+
# automatically scaled depending on the number of other panes and the
|
331
|
+
# current orientation, while subpanes are automatically the size of their
|
332
|
+
# contents.
|
333
|
+
# Another way to think about it might be that pane creates structural
|
334
|
+
# layout elements, while subpane creates embedded sections within other
|
335
|
+
# panes.
|
336
|
+
|
337
|
+
# Creates a writeable area within the current writeable area. This lets you
|
338
|
+
# update the contents of the writeable later, without disturbing the rest
|
339
|
+
# of the curent pane. If a pane or subpane with the given name already
|
340
|
+
# exists, it will just use that one instead.
|
341
|
+
# @param name [String] an identifier for the subpane. All panes and subpanes
|
342
|
+
# share the same scope, so you want to be careful with your naming.
|
343
|
+
# @return [Pane] The newly created or already existing pane.
|
344
|
+
# @macro pane_difference
|
345
|
+
# @see pane
|
299
346
|
def subpane(name, options = {})
|
300
347
|
send_json({action:'subpane', name:name}.merge(options))
|
301
348
|
return Pane.new(@engraving, name)
|
302
349
|
end
|
303
350
|
|
351
|
+
# Creates a scaled pane within the current writeable area. Where it goes
|
352
|
+
# depends on the orientation.
|
353
|
+
# @param name [String] an identifier for the subpane. All panes and subpanes
|
354
|
+
# share the same scope, so you want to be careful with your naming.
|
355
|
+
# @return [Pane] The newly created or already existing pane.
|
356
|
+
# @macro pane_difference
|
357
|
+
# @see pane
|
358
|
+
# @see orientation=
|
304
359
|
def pane(name, options = {})
|
305
360
|
send_json({action:'addpane', name:name}.merge(options))
|
306
361
|
return Pane.new(@engraving, name)
|
@@ -343,6 +398,18 @@ module Flammarion
|
|
343
398
|
return str
|
344
399
|
end
|
345
400
|
|
401
|
+
# Adds an interactive street map of a specified location.
|
402
|
+
# @option options [Integer] :zoom (13) The initial zoom level
|
403
|
+
# @option options [Boolean] :marker (true) Display a marker on the
|
404
|
+
# identified address or coordinates
|
405
|
+
# @macro add_options
|
406
|
+
# @overload map(options)
|
407
|
+
# @overload map(address, options = {})
|
408
|
+
# @param address [String] The address or landmark to look up and display.
|
409
|
+
# @overload map(latitude, longitude, options = {})
|
410
|
+
# @param latitude [Float] The latitude to display
|
411
|
+
# @param longitude [Float] The longitude to display
|
412
|
+
# @note Street map provided by http://openstreetmap.org
|
346
413
|
def map(*args)
|
347
414
|
case (args.size)
|
348
415
|
when 1
|
@@ -58,7 +58,8 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
58
58
|
|
59
59
|
}).call(this);
|
60
60
|
(function() {
|
61
|
-
var WSClient
|
61
|
+
var WSClient,
|
62
|
+
hasProp = {}.hasOwnProperty;
|
62
63
|
|
63
64
|
WSClient = (function() {
|
64
65
|
function WSClient() {
|
@@ -181,6 +182,15 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
181
182
|
};
|
182
183
|
|
183
184
|
WSClient.prototype.add = function(object, target, data) {
|
185
|
+
var key, ref, val;
|
186
|
+
if (data.style) {
|
187
|
+
ref = data.style;
|
188
|
+
for (key in ref) {
|
189
|
+
if (!hasProp.call(ref, key)) continue;
|
190
|
+
val = ref[key];
|
191
|
+
object.css(key, val);
|
192
|
+
}
|
193
|
+
}
|
184
194
|
if (data.replace) {
|
185
195
|
return target.html(object);
|
186
196
|
} else {
|
@@ -6679,7 +6679,8 @@ if (typeof module !== 'undefined') {
|
|
6679
6679
|
|
6680
6680
|
}).call(this);
|
6681
6681
|
(function() {
|
6682
|
-
var WSClient
|
6682
|
+
var WSClient,
|
6683
|
+
hasProp = {}.hasOwnProperty;
|
6683
6684
|
|
6684
6685
|
WSClient = (function() {
|
6685
6686
|
function WSClient() {
|
@@ -6802,6 +6803,15 @@ if (typeof module !== 'undefined') {
|
|
6802
6803
|
};
|
6803
6804
|
|
6804
6805
|
WSClient.prototype.add = function(object, target, data) {
|
6806
|
+
var key, ref, val;
|
6807
|
+
if (data.style) {
|
6808
|
+
ref = data.style;
|
6809
|
+
for (key in ref) {
|
6810
|
+
if (!hasProp.call(ref, key)) continue;
|
6811
|
+
val = ref[key];
|
6812
|
+
object.css(key, val);
|
6813
|
+
}
|
6814
|
+
}
|
6805
6815
|
if (data.replace) {
|
6806
6816
|
return target.html(object);
|
6807
6817
|
} else {
|
@@ -7273,7 +7283,7 @@ if (typeof module !== 'undefined') {
|
|
7273
7283
|
|
7274
7284
|
Plot = (function() {
|
7275
7285
|
Plot.prototype.default_options = {
|
7276
|
-
color: "
|
7286
|
+
color: $(document.body).css("color"),
|
7277
7287
|
replace: true,
|
7278
7288
|
size: 1.0,
|
7279
7289
|
orientation: 'vertical',
|
@@ -58,7 +58,8 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
58
58
|
|
59
59
|
}).call(this);
|
60
60
|
(function() {
|
61
|
-
var WSClient
|
61
|
+
var WSClient,
|
62
|
+
hasProp = {}.hasOwnProperty;
|
62
63
|
|
63
64
|
WSClient = (function() {
|
64
65
|
function WSClient() {
|
@@ -181,6 +182,15 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
181
182
|
};
|
182
183
|
|
183
184
|
WSClient.prototype.add = function(object, target, data) {
|
185
|
+
var key, ref, val;
|
186
|
+
if (data.style) {
|
187
|
+
ref = data.style;
|
188
|
+
for (key in ref) {
|
189
|
+
if (!hasProp.call(ref, key)) continue;
|
190
|
+
val = ref[key];
|
191
|
+
object.css(key, val);
|
192
|
+
}
|
193
|
+
}
|
184
194
|
if (data.replace) {
|
185
195
|
return target.html(object);
|
186
196
|
} else {
|
@@ -58,7 +58,8 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
58
58
|
|
59
59
|
}).call(this);
|
60
60
|
(function() {
|
61
|
-
var WSClient
|
61
|
+
var WSClient,
|
62
|
+
hasProp = {}.hasOwnProperty;
|
62
63
|
|
63
64
|
WSClient = (function() {
|
64
65
|
function WSClient() {
|
@@ -181,6 +182,15 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
181
182
|
};
|
182
183
|
|
183
184
|
WSClient.prototype.add = function(object, target, data) {
|
185
|
+
var key, ref, val;
|
186
|
+
if (data.style) {
|
187
|
+
ref = data.style;
|
188
|
+
for (key in ref) {
|
189
|
+
if (!hasProp.call(ref, key)) continue;
|
190
|
+
val = ref[key];
|
191
|
+
object.css(key, val);
|
192
|
+
}
|
193
|
+
}
|
184
194
|
if (data.replace) {
|
185
195
|
return target.html(object);
|
186
196
|
} else {
|
@@ -58,7 +58,8 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
58
58
|
|
59
59
|
}).call(this);
|
60
60
|
(function() {
|
61
|
-
var WSClient
|
61
|
+
var WSClient,
|
62
|
+
hasProp = {}.hasOwnProperty;
|
62
63
|
|
63
64
|
WSClient = (function() {
|
64
65
|
function WSClient() {
|
@@ -181,6 +182,15 @@ void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?voi
|
|
181
182
|
};
|
182
183
|
|
183
184
|
WSClient.prototype.add = function(object, target, data) {
|
185
|
+
var key, ref, val;
|
186
|
+
if (data.style) {
|
187
|
+
ref = data.style;
|
188
|
+
for (key in ref) {
|
189
|
+
if (!hasProp.call(ref, key)) continue;
|
190
|
+
val = ref[key];
|
191
|
+
object.css(key, val);
|
192
|
+
}
|
193
|
+
}
|
184
194
|
if (data.replace) {
|
185
195
|
return target.html(object);
|
186
196
|
} else {
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flammarion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -284,6 +284,7 @@ files:
|
|
284
284
|
- lib/html/Gemfile
|
285
285
|
- lib/flammarion/about.rb
|
286
286
|
- lib/flammarion/server.rb
|
287
|
+
- lib/flammarion/engraving.rb
|
287
288
|
- lib/flammarion/pane.rb
|
288
289
|
- lib/flammarion/version.rb
|
289
290
|
- lib/flammarion/revelator.rb
|