hyaslide 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b1309b029e63871fa5502347a9f0affede6510d
4
- data.tar.gz: 7ad330af25e54778f296b72f1d499234c3dd1194
3
+ metadata.gz: d773246c1bf2e1e2ab74c42db9ed6dde47d41bae
4
+ data.tar.gz: 84554225d647e2cad5f9ad5b16705465cc4ad216
5
5
  SHA512:
6
- metadata.gz: fc289bd9a4ff9e9ff7e98003885505c533c5d487f4ba07b29645fea3a9dc25a4708f6b374e6c34c9dda2f2a817de11eeff2264ac0c664b827da5503512080ad3
7
- data.tar.gz: 52296be7cd8e7d71c1c710cebf8a0f8d21ac48227a8c04d57af40768a7c79af315d805f68e1697591b1a81aca37be9c813d13a049ebe5564b8f6aafebe827620
6
+ metadata.gz: e5bee3218504024156e104a044b653e9fb01af1d82b878dc8a5c100e10c368ce5967c908e5ac0e62510d435cf01c7ee4f5f5528610d23131cdb6c5d8b99a803f
7
+ data.tar.gz: 4eccfe9359b02fdd5309d57a04161a07a92b1007c0bc3c38c43ea3d71f02f26dc2734db1b6b5cf9efa39522c3e0e91913df482775fc902c48dc9593dec3c82ff
@@ -18,201 +18,216 @@ class String
18
18
  end
19
19
  end
20
20
 
21
- module Redcarpet
22
- module Render
23
- class Hyaslide < Base
24
- def initialize
25
- super
26
- @enter_title_page = false
27
- @enter_page = false
28
- @page_count = 0
29
- clear_list_state
30
- end
21
+ module Hyaslide
22
+ class Renderer < Redcarpet::Render::Base
23
+ def self.create(name)
24
+ Class.new(Renderer) do
25
+ def self.page_name
26
+ @page_name
27
+ end
31
28
 
32
- def clear_list_state
33
- @enter_list = false
34
- @list_depth = 0
35
- end
29
+ def self.page_name=(name)
30
+ @page_name = name
31
+ end
36
32
 
37
- [
38
- # block-level calls
39
- :block_quote,
33
+ def page_name
34
+ self.class.page_name
35
+ end
36
+ end.tap{|c| c.page_name = name }
37
+ end
40
38
 
41
- # span-level calls
42
- :autolink,
43
- :underline, :raw_html,
44
- :triple_emphasis, :strikethrough,
45
- :superscript, :highlight,
39
+ def initialize
40
+ super
41
+ @enter_title_page = false
42
+ @enter_page = false
43
+ @page_count = 0
44
+ clear_list_state
45
+ end
46
46
 
47
- # footnotes
48
- :footnotes, :footnote_def, :footnote_ref,
47
+ def clear_list_state
48
+ @enter_list = false
49
+ @list_depth = 0
50
+ end
49
51
 
50
- # low level rendering
51
- #:entity, :normal_text
52
- ].each do |method|
53
- define_method method do |*args|
54
- "#{method} #{args.first}"
55
- end
52
+ [
53
+ # block-level calls
54
+ :block_quote,
55
+
56
+ # span-level calls
57
+ :autolink,
58
+ :underline, :raw_html,
59
+ :triple_emphasis, :strikethrough,
60
+ :superscript, :highlight,
61
+
62
+ # footnotes
63
+ :footnotes, :footnote_def, :footnote_ref,
64
+
65
+ # low level rendering
66
+ #:entity, :normal_text
67
+ ].each do |method|
68
+ define_method method do |*args|
69
+ "#{method} #{args.first}"
56
70
  end
71
+ end
57
72
 
58
- def hrule
59
- clear_list_state
60
- "".tap do |result|
61
- if @enter_title_page || @enter_page
62
- result <<
73
+ def hrule
74
+ clear_list_state
75
+ "".tap do |result|
76
+ if @enter_title_page || @enter_page
77
+ result <<
63
78
  <<EOD
64
- end
65
79
  end
66
80
  end
81
+ end
67
82
 
68
83
  EOD
69
- @enter_title_page = @enter_page = false
70
- end
84
+ @enter_title_page = @enter_page = false
85
+ end
71
86
 
72
- result << <<EOD
87
+ result << <<EOD
73
88
  class Hyaslide::Page#{@page_count} < Hyaslide::PageBase
74
- def content
75
- [].tap do |children|
89
+ def content
90
+ [].tap do |children|
76
91
  EOD
77
92
 
78
- @enter_page = true
79
- @page_count += 1
80
- end
93
+ @enter_page = true
94
+ @page_count += 1
81
95
  end
96
+ end
82
97
 
83
- def header(text, header_level)
84
- clear_list_state
98
+ def header(text, header_level)
99
+ clear_list_state
85
100
 
86
- if header_level > 3
87
- return " children << h#{header_level}(nil, #{text.escape})\n"
88
- end
101
+ if header_level > 3
102
+ return " children << h#{header_level}(nil, #{text.escape})\n"
103
+ end
89
104
 
90
- "".tap do |result|
91
- if @enter_title_page || @enter_page
92
- result <<
105
+ "".tap do |result|
106
+ if @enter_title_page || @enter_page
107
+ result <<
93
108
  <<EOD
94
- end
95
109
  end
96
110
  end
111
+ end
97
112
 
98
113
  EOD
99
- @enter_title_page = @enter_page = false
100
- end
114
+ @enter_title_page = @enter_page = false
115
+ end
101
116
 
102
- if header_level == 1
103
- @enter_title_page = true
104
- @title = text.escape
105
- else
106
- @enter_page = true
107
- end
117
+ if header_level == 1
118
+ @enter_title_page = true
119
+ @title = text.escape
120
+ else
121
+ @enter_page = true
122
+ end
108
123
 
109
124
 
110
- result <<
125
+ result <<
111
126
  <<EOD
112
127
  class Hyaslide::Page#{@page_count} < Hyaslide::PageBase
113
- def header
114
- h#{header_level}(nil, #{text.escape})
115
- end
128
+ def header
129
+ h#{header_level}(nil, #{text.escape})
130
+ end
116
131
 
117
- def content
118
- [].tap do |children|
132
+ def content
133
+ [].tap do |children|
119
134
  EOD
120
135
 
121
- @page_count += 1
122
- end
136
+ @page_count += 1
123
137
  end
138
+ end
124
139
 
125
- def doc_footer(*args)
140
+ def doc_footer(*args)
126
141
  <<EOD
127
- end
128
142
  end
129
143
  end
144
+ end
130
145
 
131
146
  Hyaslide.page_count = #{@page_count}
132
147
  Hyaslide.title = #{@title}
133
148
  EOD
134
- end
135
-
136
- def list_item(item, orderd)
137
- "".tap do |result|
138
- if item =~ /.*\n +children << /
139
- result << item.sub(/(.*)\n +children << /) { " li(nil, #{$1.strip.escape}),\n " }.rstrip
140
- result << ",\n"
141
- @enter_list = false
142
- else
143
- result << " li(nil, #{item.strip.escape}),\n"
144
- end
145
- end
146
- end
149
+ end
147
150
 
148
- def list(text, ordered)
149
- "".tap do |result|
150
- result << " children << ul(nil,\n"
151
- result << text.sub(/,\n\z/, "\n")
152
- result << " )\n"
151
+ def list_item(item, orderd)
152
+ "".tap do |result|
153
+ if item =~ /.*\n +children << /
154
+ result << item.sub(/(.*)\n +children << /) { " li(nil, #{$1.strip.escape}),\n " }.rstrip
155
+ result << ",\n"
153
156
  @enter_list = false
157
+ else
158
+ result << " li(nil, #{item.strip.escape}),\n"
154
159
  end
155
160
  end
161
+ end
156
162
 
157
- def link(link, title, content)
158
- "<a>{href: #{link.escape}, target: \"_blank\"}, #{content.escape}</a>"
163
+ def list(text, ordered)
164
+ "".tap do |result|
165
+ result << " children << ul(nil,\n"
166
+ result << text.sub(/,\n\z/, "\n")
167
+ result << " )\n"
168
+ @enter_list = false
159
169
  end
170
+ end
160
171
 
161
- def image(link, title, alt_text)
162
- "<img>{className: \"#{alt_text}\", src: #{link.escape}}</img>"
163
- end
172
+ def link(link, title, content)
173
+ "<a>{href: #{link.escape}, target: \"_blank\"}, #{content.escape}</a>"
174
+ end
164
175
 
165
- def block_code(code, language)
166
- clear_list_state
167
-
168
- formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true)
169
- lexer = case language
170
- when 'ruby'
171
- Rouge::Lexers::Ruby.new
172
- when 'javascript'
173
- Rouge::Lexers::Javascript.new
174
- else
175
- Rouge::Lexers::PlainText.new
176
- end
177
- highlight = formatter.format(lexer.lex(code))
178
- " children << code({ dangerouslySetInnerHTML: { __html: %q{#{highlight}} } })\n"
179
- end
176
+ def image(link, title, alt_text)
177
+ href = "assets/#{page_name}/images/#{link}"
178
+ "<img>{className: \"#{alt_text}\", src: #{href.escape}}</img>"
179
+ end
180
180
 
181
- def block_html(html)
182
- clear_list_state
183
- " children << code({ dangerouslySetInnerHTML: { __html: %q{#{html}} } })\n"
184
- end
181
+ def block_code(code, language)
182
+ clear_list_state
183
+
184
+ formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true)
185
+ lexer = case language
186
+ when 'ruby'
187
+ Rouge::Lexers::Ruby.new
188
+ when 'javascript'
189
+ Rouge::Lexers::Javascript.new
190
+ else
191
+ Rouge::Lexers::PlainText.new
192
+ end
193
+ highlight = formatter.format(lexer.lex(code))
194
+ " children << code({ dangerouslySetInnerHTML: { __html: %q{#{highlight}} } })\n"
195
+ end
185
196
 
186
- def emphasis(*args)
187
- "# #{args}"
188
- end
197
+ def block_html(html)
198
+ clear_list_state
199
+ " children << code({ dangerouslySetInnerHTML: { __html: %q{#{html}} } })\n"
200
+ end
189
201
 
190
- def double_emphasis(*args)
191
- "<strong>#{args.first}</strong>"
192
- end
202
+ def emphasis(*args)
203
+ "# #{args}"
204
+ end
193
205
 
194
- def paragraph(text)
195
- lines = text.split(/ $/)
196
- if text[0] == '%'
197
- class_name = text[1...text.index(':')]
198
- lines[0] = lines.first[(lines.first.index(':') + 1)...lines.first.length].lstrip
199
- " children << p({className:\"#{class_name}\"}, #{lines.map{|l| l.escape}.join(',Hyalite.create_element(\'br\'),')})\n"
200
- else
201
- " children << p(nil, #{lines.map{|l| l.escape}.join(',Hyalite.create_element(\'br\'),')})\n"
202
- end
203
- end
206
+ def double_emphasis(*args)
207
+ "<strong>#{args.first}</strong>"
208
+ end
204
209
 
205
- def table(header, body)
206
- "#{header}#{body}"
210
+ def paragraph(text)
211
+ lines = text.split(/ $/)
212
+ if text[0] == '%'
213
+ class_name = text[1...text.index(':')]
214
+ lines[0] = lines.first[(lines.first.index(':') + 1)...lines.first.length].lstrip
215
+ " children << p({className:\"#{class_name}\"}, #{lines.map{|l| l.escape}.join(',Hyalite.create_element(\'br\'),')})\n"
216
+ else
217
+ " children << p(nil, #{lines.map{|l| l.escape}.join(',Hyalite.create_element(\'br\'),')})\n"
207
218
  end
219
+ end
208
220
 
209
- def table_row(content)
210
- content + "\n"
211
- end
221
+ def table(header, body)
222
+ "#{header}#{body}"
223
+ end
212
224
 
213
- def table_cell(content, alignment)
214
- content + "\t"
215
- end
225
+ def table_row(content)
226
+ content + "\n"
227
+ end
228
+
229
+ def table_cell(content, alignment)
230
+ content + "\t"
216
231
  end
217
232
  end
218
233
  end
@@ -7,7 +7,6 @@ require_relative './render_hyaslide'
7
7
 
8
8
  module Hyaslide
9
9
  class SlideLoader
10
- MARKDOWN = Redcarpet::Markdown.new(Redcarpet::Render::Hyaslide, fenced_code_blocks: true)
11
10
 
12
11
  attr_reader :slides
13
12
 
@@ -15,9 +14,11 @@ module Hyaslide
15
14
  @slides = []
16
15
  end
17
16
 
18
- def load_slide(name)
17
+ def init_slide(name)
19
18
  Dir.mkdir('app/slides') unless Dir.exist?('app/slides')
20
- Dir.mkdir(src_path(name)) unless Dir.exist?(src_path(name))
19
+ Dir.mkdir('app/scripts') unless Dir.exist?('app/scripts')
20
+ Dir.mkdir(SlideLoader.src_path(name)) unless Dir.exist?(SlideLoader.src_path(name))
21
+ Dir.mkdir(SlideLoader.script_path(name)) unless Dir.exist?(SlideLoader.script_path(name))
21
22
 
22
23
  File.foreach("data/#{name}/slide.md") do |line|
23
24
  if line =~ /\A# (.+)/
@@ -26,26 +27,47 @@ module Hyaslide
26
27
  end
27
28
  end
28
29
 
30
+ SlideLoader.load_slide(name)
31
+ end
32
+
33
+ def self.load_slide(name)
29
34
  File.open("#{src_path(name)}/pages.rb", "w+") do |f|
30
35
  data = File.read("data/#{name}/slide.md")
31
- f.write MARKDOWN.render(data)
36
+ markdown = Redcarpet::Markdown.new(Hyaslide::Renderer.create(name), fenced_code_blocks: true)
37
+ f.write markdown.render(data)
38
+ end
39
+
40
+ if File.exist?("data/#{name}/script.md")
41
+ File.open("#{script_path(name)}/script.html", "w+") do |f|
42
+ script = File.read("data/#{name}/script.md")
43
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(hard_wrap: true), autolink: true, fenced_code_blocks: true)
44
+ f.write markdown.render(script)
45
+ end
32
46
  end
33
47
 
34
48
  File.open("#{src_path(name)}/app.rb", "w+") do |f|
35
49
  f.write Tilt::StringTemplate.new(File.expand_path('../../../template/app.rb', __FILE__)).render(Object.new, name: name)
36
50
  end
51
+
52
+ File.open("#{src_path(name)}/script.rb", "w+") do |f|
53
+ f.write Tilt::StringTemplate.new(File.expand_path('../../../template/script.rb', __FILE__)).render(Object.new, name: name)
54
+ end
37
55
  end
38
56
 
39
- def src_path(name)
57
+ def self.src_path(name)
40
58
  "app/slides/#{name}"
41
59
  end
42
60
 
61
+ def self.script_path(name)
62
+ "app/scripts/#{name}"
63
+ end
64
+
43
65
  def add_slide(name)
44
- load_slide(name)
66
+ init_slide(name)
45
67
 
46
68
  EM.defer do
47
- FSSM.monitor("data/#{@name}", "slide.md") do
48
- update {|base, relative| SlideLoader.load_slide(@name) }
69
+ FSSM.monitor("data/#{name}", %w(slide.md script.md)) do
70
+ update {|base, relative| Hyaslide::SlideLoader.load_slide(name) }
49
71
  delete {|base, relative|}
50
72
  create {|base, relative|}
51
73
  end
@@ -1,3 +1,3 @@
1
1
  module Hyaslide
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,19 +1,23 @@
1
1
  require 'slide'
2
2
  require 'page_base'
3
3
  require 'slides/#{name}/pages'
4
+ require 'browser/socket'
5
+ require 'browser/location'
4
6
 
5
7
  Hyaslide.slide_name = '#{name}'
6
8
 
7
9
  module App
8
- def self.render
9
- Hyalite.render(Hyalite.create_element(Hyaslide::Slide, nil), $document['.hyaslide'])
10
+ def self.render(ws)
11
+ Hyalite.render(Hyalite.create_element(Hyaslide::Slide, {ws:ws}), $document['.hyaslide'])
10
12
  end
11
13
  end
12
14
 
13
15
  $document.ready do
16
+ ws = Browser::Socket.new("ws://\#{$window.location.host}/push_notification/start/slide/#{name}")
17
+
14
18
  $window.on(:resize) do
15
- App.render
19
+ App.render(ws)
16
20
  end
17
21
 
18
- App.render
22
+ App.render(ws)
19
23
  end
@@ -51,7 +51,7 @@ module Hyaslide
51
51
  end
52
52
 
53
53
  def initial_state
54
- page_num = $window.location.uri.sub(/.*\/#\/([0-9]+)/, '\1').to_i
54
+ page_num = $window.location.uri.sub(/.*#([0-9]+)/, '\1').to_i
55
55
 
56
56
  {
57
57
  page_number: page_num,
@@ -63,7 +63,15 @@ module Hyaslide
63
63
 
64
64
  def component_did_mount
65
65
  $window.on(:keydown) do |evt|
66
- handle_key_down(evt)
66
+ handle_key_down(evt.code)
67
+ end
68
+
69
+ @props[:ws].on(:message) do |msg|
70
+ (event, value) = msg.data.split(':')
71
+ case event
72
+ when 'keydown'
73
+ handle_key_down(value.to_i)
74
+ end
67
75
  end
68
76
 
69
77
  router = Router.new
@@ -75,8 +83,8 @@ module Hyaslide
75
83
  $window.location.assign("/#{Hyaslide.slide_name}##{num}")
76
84
  end
77
85
 
78
- def handle_key_down(evt)
79
- case evt.code
86
+ def handle_key_down(keycode)
87
+ case keycode
80
88
  when 39
81
89
  page_to(@state[:page_number] + 1) if @state[:page_number] < Hyaslide.page_count
82
90
  when 37
@@ -96,7 +104,7 @@ module Hyaslide
96
104
  when 70
97
105
  set_state(footer_visible: !@state[:footer_visible])
98
106
  else
99
- puts "keycode = #{evt.code}"
107
+ puts "keycode = #{keycode}"
100
108
  end
101
109
  end
102
110
 
@@ -119,7 +127,7 @@ module Hyaslide
119
127
  div({
120
128
  className: 'slide',
121
129
  style: {zoom: zoom, top: "#{top}px", left: "#{left}px"},
122
- onKeyDown: -> (evt) { handle_key_down(evt) }
130
+ onKeyDown: -> (evt) { handle_key_down(evt.code) }
123
131
  },
124
132
  pages(SLIDE_HEIGHT * zoom)
125
133
  ),
@@ -0,0 +1,7 @@
1
+ # Sample
2
+
3
+ Write script here.
4
+
5
+ This page accessible from psth: '/script/sample'
6
+
7
+ You can controll the slide from this page. Press arrow keys.
@@ -1,4 +1,5 @@
1
1
  require 'sinatra'
2
+ require 'sinatra-websocket'
2
3
  require 'opal'
3
4
  require 'opal/sprockets'
4
5
 
@@ -28,6 +29,8 @@ class Server < Sinatra::Base
28
29
  end
29
30
 
30
31
  set :opal, opal
32
+ set :sockets, []
33
+ set :slide_sockets, {}
31
34
  enable :sessions
32
35
  end
33
36
 
@@ -36,13 +39,38 @@ class Server < Sinatra::Base
36
39
  haml :index
37
40
  end
38
41
 
42
+ get "/favicon.ico" do
43
+ end
44
+
39
45
  get '/:slide_name' do
40
46
  @slide_name = params['slide_name']
41
47
  haml :slide
42
48
  end
43
49
 
44
- get "/favicon.ico" do
50
+ get '/script/:slide_name' do
51
+ @slide_name = params['slide_name']
52
+ @script_html = "<h1>Test</h1>"
53
+ haml :script
45
54
  end
46
- end
47
-
48
55
 
56
+ get '/push_notification/start/:page/:slide_name' do
57
+ request.websocket do |ws|
58
+ ws.onopen do
59
+ if params['page'] == 'slide'
60
+ slide_name = params['slide_name']
61
+ (settings.slide_sockets[slide_name] ||= []) << ws
62
+ end
63
+ settings.sockets << ws
64
+ end
65
+ ws.onmessage do |msg|
66
+ (slide_name, evt, value) = msg.split(':')
67
+ EM.next_tick do
68
+ settings.slide_sockets[slide_name].each{|s| s.send("#{evt}:#{value}") }
69
+ end
70
+ end
71
+ ws.onclose do
72
+ settings.sockets.delete(ws)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -10,4 +10,4 @@
10
10
  %ul
11
11
  - @slides.each do |slide|
12
12
  %li
13
- %a{href: slide[:name]}= slide[:title]
13
+ %a{href: slide[:name]}= "[#{slide[:name]}] \"#{slide[:title]}\""
@@ -0,0 +1,10 @@
1
+ !!!
2
+ %html(lang="en" data-framework="hyalite")
3
+ %head
4
+ %meta{charset:"utf-8"}
5
+ %title= "Script of #{@slide_name}"
6
+
7
+ %body
8
+ %section.script
9
+
10
+ = ::Opal::Sprockets.javascript_include_tag("slides/#{@slide_name}/script", sprockets: settings.opal.sprockets, prefix: '/assets', debug: true)
@@ -0,0 +1,24 @@
1
+ require 'hyalite'
2
+ require 'browser/http'
3
+ require 'browser/socket'
4
+ require 'browser/location'
5
+
6
+ class Script
7
+ include Hyalite::Component
8
+ include Hyalite::Component::ShortHand
9
+
10
+ def render
11
+ div({dangerouslySetInnerHTML: { __html: @props[:script_html]}})
12
+ end
13
+ end
14
+
15
+ $document.ready do
16
+ ws = Browser::Socket.new("ws://\#{$window.location.host}/push_notification/start/script/#{name}")
17
+ $window.on('keydown') do |evt|
18
+ ws.write("#{name}:keydown:\#{evt.code}")
19
+ end
20
+
21
+ response = Browser::HTTP.get!('/assets/scripts/#{name}/script.html')
22
+ Hyalite.render(Hyalite.create_element(Script, script_html: response.text), $document['.script'])
23
+ end
24
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyaslide
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - youchan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-11 00:00:00.000000000 Z
11
+ date: 2016-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sinatra-websocket
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: thin
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -249,10 +263,13 @@ files:
249
263
  - template/project/assets/images/turtle.png
250
264
  - template/project/config.ru
251
265
  - template/project/data/sample/css/custom.css
266
+ - template/project/data/sample/script.md
252
267
  - template/project/data/sample/slide.md
253
268
  - template/project/server.rb
254
269
  - template/project/views/index.haml
270
+ - template/project/views/script.haml
255
271
  - template/project/views/slide.haml
272
+ - template/script.rb
256
273
  homepage: https://github.com/youchan/hyalide
257
274
  licenses:
258
275
  - MIT