tkn2 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c47a9bc8f71f08d678661bd99720f72c2fdc065
4
+ data.tar.gz: 5700de099467bd9c1c45166a6ecdf7c189e1e474
5
+ SHA512:
6
+ metadata.gz: be808afbf8b891c5f58e59f712829a85498a80ff9758b78797e149f3ef5c1280bd32a957c00dd475258be2ceb2c4ccf32cfb6601b8d120933dad87133fbac9c8
7
+ data.tar.gz: 41a2b35ebfef372eceb17213c39324cae3501e458c86521d8214fabcbe23dab3ffb683f47ff4caeb2bb9e065b1368a55e4f3eb22367f66c541812f35e8203a98
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1 @@
1
+ 2.0.0-p247
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tkn2.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sergio Gil
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,148 @@
1
+ # Tkn2
2
+
3
+ Tkn2 is a presentation tool for the terminal. It's heavily inspired in [Xavier Noria](http://www.hashref.com/)'s
4
+ [tkn](https://github.com/fxn/tkn) (Terminal Keynote).
5
+
6
+ See [usage](#usage).
7
+
8
+ Tkn2 is work in progress. First goal is compatibility with tkn (it's almost there) and, from there, keep building
9
+ interesting features. Although the initial idea is to clone it, it might drop complete compatibility in some future
10
+ point.
11
+
12
+ Main differences with tkn:
13
+
14
+ * The commands are not available in the general namespace; you need to wrap the presentation in a `Tkn2.deck` block
15
+ * It's packed as a gem, and intended to use with bundler via a `Gemfile`. That may sound like overkill but, with tkn2
16
+ evolving, it's nice to have each presentation stored with a explicit reference to the verion of tkn2 it was written
17
+ for (tkn solves this having the script vendored)
18
+ * It uses [ncurses](http://www.gnu.org/software/ncurses/) instead of direct printing. This gets it some nice behaviour
19
+ like autoredrawing when resizing windows or changing font size
20
+ * It aims to have the code better split and organized, in order to allow better extensibility and an easier time when
21
+ adding features in the future. This is, however, a claim to be proofed.
22
+
23
+ ## Usage
24
+
25
+ Have a `.rb` file requiring `tkn2` with a `Tkn2.deck` block. In that block you can use all the available commands.
26
+ You'll run that file to start the presentation
27
+
28
+ ```ruby
29
+ require 'tkn2'
30
+
31
+ Tkn2.deck do
32
+ # here goes your presentation
33
+ end
34
+ ```
35
+
36
+ The easiest way to do this is to have a `Gemfile` like this:
37
+
38
+ ```ruby
39
+ source 'https://rubygems.org'
40
+
41
+ gem 'tkn2'
42
+ ```
43
+
44
+ And then run the presentation using bundler:
45
+
46
+ ```
47
+ $ bundle exec ruby mypresentation.rb
48
+ ```
49
+
50
+ ### Available commands
51
+
52
+ Each command generates a slide. These are the commands available:
53
+
54
+ #### `center`
55
+
56
+ Generates a slide with the given text, centered line by line.
57
+
58
+ ```ruby
59
+ center <<-EOS
60
+ Tkn2 Less is more
61
+ EOS
62
+ ```
63
+
64
+ #### `block`
65
+
66
+ Generates a slide with the given text, centered as a whole (useful for bulleted lists).
67
+
68
+ ```ruby
69
+ block <<-EOS
70
+ This is why Tkn2 is cool:
71
+ * Reason number 1
72
+ * Reason number 2
73
+ EOS
74
+ ```
75
+
76
+ #### `code`
77
+
78
+ Highlights the code given (using [pygments.rb](https://github.com/tmm1/pygments.rb) and
79
+ [pygments](http://pygments.org/)) and displays it centered.
80
+
81
+ ```ruby
82
+ code <<-RUBY
83
+ puts 'hello'
84
+ RUBY
85
+ ```
86
+
87
+ #### `section`
88
+
89
+ Generates a slide with the section title centered and proceeds with the contained slides.
90
+
91
+ ```ruby
92
+ section 'This is a section' do
93
+ center 'Slide n. 1'
94
+ center 'Slide n. 2'
95
+ end
96
+ ```
97
+
98
+ See the [`examples/`](examples/) directory.
99
+
100
+ Apart from that, it's Ruby! So you're not limited to use string literals to generate the content and you can do whatever
101
+ you want (read from the network, make calculations, etc.).
102
+
103
+ ### Keys
104
+
105
+ These are the keys you can use to navigate the presentation:
106
+
107
+ * Down, Right, Enter, Space, Page Down, N: next slide
108
+ * Up, Left, Backspace, Page Up, P: previous slide
109
+ * Home: first slide
110
+ * Q: quit
111
+
112
+ ## TODO / Roadmap
113
+
114
+ I'm writing Tkn2 as a way to experiment. This may make the roadmap a bit strange, as I'll be trying to bring to the
115
+ terminal the most features common in graphical presentation software, even when it will be difficult and not very practical in many cases.
116
+
117
+ That said:
118
+
119
+ * (Auto)reload [1]
120
+ * Images [1]
121
+ * Better control of *overflow* (currently the presentation crashes if the content doesn't fit in the screen). I'm
122
+ playing with the idea of having *scroll*, something usually not present in graphical presentation software and that
123
+ can be useful to present code without using a tiny font size
124
+ * A generator
125
+ * Colors and themes
126
+ * Plugin system. More as an exercise, I want to try to keep the core small and simple and implement features as plugins
127
+ * A way to compose slides with more than one element. Tools to generate content (ASCII art diagrams, etc.)
128
+ * Speaker's notes (with next slide, etc.). The only practical way of doing this I see is implementing a *server* and
129
+ having two different *clients*. This *client-server* mode is an interesting feature in itself, for remote
130
+ presentations through the network
131
+
132
+ [1] Already present in tkn.
133
+
134
+ ## Thanks
135
+
136
+ * [Xavi](http://www.hashref.com/), for the great inspiration and brilliant hack
137
+
138
+ ## Contributing
139
+
140
+ 1. Fork it
141
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
142
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
143
+ 4. Push to the branch (`git push origin my-new-feature`)
144
+ 5. Create new Pull Request
145
+
146
+ ## License
147
+
148
+ Released under the MIT License, Copyright (c) 2013 Sergio Gil.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,397 @@
1
+ require 'tkn2'
2
+
3
+ Tkn2.deck do
4
+ center <<-EOS
5
+ Constant Autoloading in Ruby on Rails
6
+
7
+
8
+ Xavier Noria
9
+ @fxn
10
+
11
+ BaRuCo 2012
12
+ EOS
13
+
14
+ code <<-EOS
15
+ require 'application_controller'
16
+ require 'post'
17
+
18
+ class PostsController < ApplicationController
19
+ def index
20
+ @posts = Post.all
21
+ end
22
+ end
23
+ EOS
24
+
25
+ code <<-EOS
26
+ class PostsController < ApplicationController
27
+ def index
28
+ @posts = Post.all
29
+ end
30
+ end
31
+ EOS
32
+
33
+ section "Constants Refresher" do
34
+ code <<-EOS
35
+ X = 1
36
+ EOS
37
+
38
+ code <<-EOS
39
+ class C
40
+ end
41
+ EOS
42
+
43
+ code <<-EOS
44
+ # ordinary class definition
45
+ class C < D
46
+ include M
47
+ end
48
+
49
+ # equivalent modulus details
50
+ C = Class.new(D) do
51
+ include M
52
+ end
53
+
54
+ # class name comes from the constant
55
+ C.name # => "C"
56
+ EOS
57
+
58
+ code <<-EOS
59
+ ArgumentError FalseClass
60
+ Array Fiber
61
+ BasicObject File
62
+ Bignum FileTest
63
+ Binding Fixnum
64
+ Class Float
65
+ Comparable GC
66
+ Complex Gem
67
+ Config Hash
68
+ Dir IO
69
+ Encoding IOError
70
+ EncodingError IndexError
71
+ Enumerable Integer
72
+ Enumerator Interrupt
73
+ Errno Kernel
74
+ Exception ...
75
+ EOS
76
+
77
+ center <<-EOS
78
+ Constants are stored in modules
79
+ EOS
80
+
81
+ code <<-EOS
82
+ # rubinius/kernel/common/module.rb
83
+
84
+ class Module
85
+ attr_reader :constant_table
86
+ attr_writer :method_table
87
+ ...
88
+ end
89
+ EOS
90
+
91
+ code <<-EOS
92
+ module M
93
+ X = 1
94
+ end
95
+ EOS
96
+
97
+ code <<-EOS
98
+ # ordinary class definition in namespace
99
+ module XML
100
+ class SAXParser
101
+ end
102
+ end
103
+
104
+ # equivalent modulus details to
105
+ module XML
106
+ SAXParser = Class.new
107
+ end
108
+ EOS
109
+
110
+ center <<-EOS
111
+ Constants API
112
+ EOS
113
+
114
+ center <<-EOS
115
+ Constant Name Resolution (1)
116
+ EOS
117
+
118
+ code <<-EOS
119
+ module M
120
+ X = 1
121
+ end
122
+ EOS
123
+
124
+ code <<-EOS
125
+ module Admin
126
+ class UsersController < ApplicationController
127
+ end
128
+ end
129
+ EOS
130
+
131
+ center <<-EOS
132
+ Constant Name Resolution (2)
133
+ EOS
134
+
135
+ code <<-EOS
136
+ M::X
137
+ EOS
138
+
139
+ center <<-EOS
140
+ Constant Name Resolution (3)
141
+ EOS
142
+
143
+ code <<-EOS
144
+ module M
145
+ module N
146
+ class C < D
147
+ X
148
+ end
149
+ end
150
+ end
151
+ EOS
152
+ end
153
+
154
+ section "Constant Autoloading" do
155
+ code <<-EOS
156
+ module Admin
157
+ class UsersController < ApplicationController
158
+ def index
159
+ @users = User.all
160
+ end
161
+ end
162
+ end
163
+ EOS
164
+
165
+ code <<-EOS
166
+ # active_support/dependencies.rb
167
+
168
+ def self.const_missing(const_name)
169
+ name # => "Admin::UsersController"
170
+ const_name # => :User
171
+ end
172
+ EOS
173
+
174
+ code <<-EOS
175
+ config.autoload_paths
176
+ EOS
177
+
178
+ block <<-EOS
179
+ admin/users_controller/user.rb
180
+ admin/users_controller/user
181
+
182
+ # trade-offs
183
+
184
+ admin/user.rb
185
+ admin/user
186
+
187
+ # trade-offs
188
+
189
+ user.rb # FOUND
190
+ EOS
191
+
192
+ code <<-EOS
193
+ class Contact < ActiveRecord::Base
194
+ after_commit :register_event
195
+
196
+ def register_event
197
+ Worker::EventRegister.perform_async(...)
198
+ end
199
+ end
200
+ EOS
201
+
202
+ block <<-EOS
203
+ contact/worker.rb
204
+ contact/worker
205
+
206
+ # trade-offs
207
+
208
+ worker.rb
209
+ worker # FOUND
210
+ EOS
211
+
212
+ code <<-EOS
213
+ Object.const_set("Worker", Module.new)
214
+ EOS
215
+
216
+ block <<-EOS
217
+ We keep track of:
218
+
219
+ * Fully qualified names of autoloaded constants
220
+
221
+ * Their corresponding file names
222
+ EOS
223
+
224
+ center <<-EOS
225
+ Kernel#load and Kernel#require are wrapped
226
+ EOS
227
+
228
+ # center <<-EOS
229
+ # require_dependency "sti_grandchildren"
230
+ # EOS
231
+
232
+ block <<-EOS
233
+ Problem: Which Is The Nesting?
234
+ EOS
235
+
236
+ code <<-EOS
237
+ # active_support/dependencies.rb
238
+
239
+ def self.const_missing(const_name)
240
+ name # => "Admin::UsersController"
241
+ const_name # => :User
242
+ end
243
+ EOS
244
+
245
+ code <<-EOS
246
+ module M
247
+ module N
248
+ # nesting: [M::N, M]
249
+ end
250
+ end
251
+
252
+ module M::N
253
+ # nesting: [M::N]
254
+ end
255
+
256
+ module A::B
257
+ module M::N
258
+ # nesting: [M::N, A::B]
259
+ end
260
+ end
261
+ EOS
262
+
263
+ code <<-EOS1
264
+ module M
265
+ Module.new.module_eval <<-EOS
266
+ # nesting: [#<Module:0x007fa4a284f708>, M]
267
+ EOS
268
+ end
269
+ EOS1
270
+
271
+ center <<-EOS
272
+ Trade-off for Named Modules:
273
+ EOS
274
+
275
+ center <<-EOS
276
+ The name reflects the nesting
277
+ EOS
278
+
279
+ code <<-EOS
280
+ module M
281
+ module N
282
+ # nesting: [M::N, M]
283
+ end
284
+ end
285
+ EOS
286
+
287
+ center <<-EOS
288
+ Trade-off for Anonymous Modules
289
+ EOS
290
+
291
+ code <<-EOS
292
+ # active_support/dependencies.rb
293
+
294
+ def const_missing(const_name)
295
+ from_mod = anonymous? ? ::Object : self
296
+ ...
297
+ end
298
+ EOS
299
+
300
+ block <<-EOS
301
+ Problem: Which Is The Resolution Algorithm?
302
+ EOS
303
+
304
+ code <<-EOS
305
+ X = 1
306
+
307
+ module M
308
+ X # => 1
309
+ end
310
+
311
+ M::X # => NameError
312
+ EOS
313
+
314
+ center <<-EOS
315
+ Trade-off
316
+ EOS
317
+
318
+ code <<-EOS
319
+ # active_support/dependencies.rb
320
+
321
+ from_mod.parents.any? do |p|
322
+ p.const_defined?(const_name, false)
323
+ end
324
+ EOS
325
+
326
+ center <<-EOS
327
+ No attempt is made to follow ancestors
328
+ EOS
329
+
330
+ center <<-EOS
331
+ Corollary: Active Support does not emulate
332
+ constant name resolution algorithms
333
+ EOS
334
+ end
335
+
336
+ section "Request Flow" do
337
+ code <<-EOS
338
+ config.cache_classes
339
+ EOS
340
+
341
+ code <<-EOS
342
+ ActiveSupport::FileUpdateChecker
343
+ EOS
344
+
345
+ code <<-EOS
346
+ config.autoload_once_paths
347
+ config.explicitly_unloadable_constants
348
+ EOS
349
+
350
+ code <<-EOS
351
+ # rails/application.rb
352
+
353
+ unless config.cache_classes
354
+ middleware.use ActionDispatch::Reloader, ...
355
+ end
356
+ EOS
357
+
358
+ block <<-EOS
359
+ What is watched and reloaded:
360
+
361
+ * Routes
362
+
363
+ * Locales
364
+
365
+ * Application files:
366
+
367
+ - Ruby files under autoload_*
368
+
369
+ - db/(schema.rb|structure.sql)
370
+ EOS
371
+
372
+ center <<-EOS
373
+ If files have changed, autoloaded constants
374
+ are wiped at the beginning of the request
375
+ EOS
376
+
377
+ code <<-EOS
378
+ # active_support/dependencies.rb
379
+
380
+ autoloaded_constants.each do |const|
381
+ remove_constant const
382
+ end
383
+
384
+ explicitly_unloadable_constants.each do |const|
385
+ remove_constant const
386
+ end
387
+ EOS
388
+
389
+ center <<-EOS
390
+ Constant access triggers const_missing again
391
+ because the constants are gone
392
+ EOS
393
+ end
394
+
395
+ section "That's all, thanks!" do
396
+ end
397
+ end
@@ -0,0 +1,23 @@
1
+ require 'tkn2'
2
+
3
+ Tkn2.deck do
4
+ center "wadus üníçöde"
5
+
6
+ code <<-EOS
7
+ require 'application_controller'
8
+ require 'post'
9
+
10
+ class PostsController < ApplicationController
11
+ def index
12
+ @posts = Post.all
13
+ end
14
+ end
15
+ EOS
16
+
17
+ section "This is a section" do
18
+ center <<-EOS
19
+ Hola
20
+ Hola
21
+ EOS
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require "tkn2/version"
2
+ require "tkn2/slide"
3
+ require "tkn2/deck"
4
+ require "tkn2/screen"
5
+ require "tkn2/ansi_reader"
6
+ require "tkn2/content_block"
7
+ require "tkn2/utils"
8
+
9
+ module Tkn2
10
+ def self.deck(&block)
11
+ Deck.new.tap do |deck|
12
+ deck.instance_eval(&block)
13
+ end.present!
14
+ end
15
+ end
@@ -0,0 +1,71 @@
1
+ require 'stringio'
2
+
3
+ module Tkn2
4
+ class ANSIReader
5
+ SText = 0
6
+ SCode = 1
7
+
8
+ def parse(content)
9
+ io = StringIO.new(content)
10
+ state = SText
11
+ buffer = ''
12
+ while c = io.getc
13
+ case state
14
+ when SCode
15
+ if c == 'm'
16
+ code(buffer)
17
+ state = SText
18
+ else
19
+ buffer << c
20
+ end
21
+ when SText
22
+ if c == ?\e
23
+ state = SCode
24
+ buffer = ''
25
+ else
26
+ char(c)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class Screen < ANSIReader
33
+ def initialize(window)
34
+ @window = window
35
+ end
36
+
37
+ def code(c)
38
+ c.sub(/\A\[/, '').split(';').each do |n|
39
+ @window.attrset(MAP[n]) if MAP[n]
40
+ end
41
+ end
42
+
43
+ MAP = {
44
+ "00" => Curses::A_NORMAL,
45
+ "01" => Curses::A_BOLD,
46
+ }
47
+
48
+ def char(c)
49
+ @window.addstr c
50
+ end
51
+ end
52
+
53
+ class Remover < ANSIReader
54
+ def remove(content)
55
+ parse(content)
56
+ string
57
+ end
58
+
59
+ def code(c)
60
+ end
61
+
62
+ def char(c)
63
+ string << c
64
+ end
65
+
66
+ def string
67
+ @string ||= ''
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,17 @@
1
+ module Tkn2
2
+ class ContentBlock
3
+ attr_reader :content
4
+
5
+ def initialize(content)
6
+ @content = content
7
+ end
8
+
9
+ def height
10
+ content.lines.size
11
+ end
12
+
13
+ def width
14
+ content.lines.map(&:size).max
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,59 @@
1
+ module Tkn2
2
+ class Deck
3
+ def initialize
4
+ @slides = []
5
+ @current = 0
6
+ @renderer = Screen.new
7
+ end
8
+
9
+ def present!
10
+ @renderer.render(self)
11
+ end
12
+
13
+ def current
14
+ @slides[@current]
15
+ end
16
+
17
+ def next
18
+ @current += 1 unless last?
19
+ end
20
+
21
+ def prev
22
+ @current -= 1 unless first?
23
+ end
24
+
25
+ def first
26
+ @current = 0
27
+ end
28
+
29
+ def first?
30
+ @current == 0
31
+ end
32
+
33
+ def last?
34
+ @current == @slides.size - 1
35
+ end
36
+
37
+ private
38
+
39
+ def self.slide_method(name, klass)
40
+ define_method name do |*args|
41
+ add_slide klass.new(*args)
42
+ end
43
+ end
44
+
45
+ def add_slide(slide)
46
+ @slides << slide
47
+ end
48
+
49
+ slide_method :center, Slide::Center
50
+ slide_method :code, Slide::Code
51
+ slide_method :block, Slide
52
+ slide_method :section_header, Slide::SectionHeader
53
+
54
+ def section(title, &block)
55
+ section_header title
56
+ yield
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,48 @@
1
+ require 'curses'
2
+
3
+ module Tkn2
4
+ class Screen
5
+ def initialize
6
+ Curses.init_screen
7
+ Curses.cbreak
8
+ Curses.nl
9
+ Curses.noecho
10
+ Curses.curs_set 0
11
+ Curses.stdscr.keypad(true)
12
+ end
13
+
14
+ def render(deck)
15
+ loop do
16
+ break unless deck.current
17
+
18
+ Curses.clear
19
+ place_content deck.current.block
20
+
21
+ case Curses.getch
22
+ when 'q'
23
+ break
24
+ when 'n', Curses::Key::DOWN, Curses::Key::RIGHT, ' ', Curses::Key::ENTER, Curses::Key::NPAGE
25
+ deck.next
26
+ when 'p', Curses::Key::UP, Curses::Key::LEFT, Curses::Key::BACKSPACE, Curses::Key::PPAGE
27
+ deck.prev
28
+ when Curses::Key::HOME
29
+ deck.first
30
+ end
31
+ end
32
+
33
+ Curses.stdscr.close
34
+ end
35
+
36
+ private
37
+
38
+ def place_content(content)
39
+ raw_content = ContentBlock.new(ANSIReader::Remover.new.remove(content.content))
40
+ top = (Curses.lines - raw_content.height) / 2
41
+ left = (Curses.cols - raw_content.width) / 2
42
+ window = Curses.stdscr.subwin(raw_content.height, raw_content.width, top, left)
43
+ ANSIReader::Screen.new(window).parse(content.content)
44
+ window.refresh
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,50 @@
1
+ module Tkn2
2
+ class Slide
3
+ def initialize(*args)
4
+ @args = args
5
+ end
6
+
7
+ def block
8
+ ContentBlock.new(content)
9
+ end
10
+
11
+ def content
12
+ Utils.strip_heredoc(raw_content)
13
+ end
14
+
15
+ def raw_content
16
+ @args.first
17
+ end
18
+
19
+ class Center < Slide
20
+ def content
21
+ super.lines.map { |l| l.chomp.center(width) }.join("\n")
22
+ end
23
+
24
+ def width
25
+ ContentBlock.new(Utils.strip_heredoc(raw_content)).width
26
+ end
27
+ end
28
+
29
+ require 'pygments'
30
+
31
+ class Code < Slide
32
+ def lexer
33
+ @args[1] || 'ruby'
34
+ end
35
+
36
+ def content
37
+ # Pygments.highlight(super, formatter: 'terminal256', lexer: lexer)
38
+ Pygments.highlight(super, formatter: 'terminal256', lexer: lexer, options: {style: 'bw'})
39
+ end
40
+ end
41
+
42
+ class SectionHeader < Center
43
+ def content
44
+ line = ' ❧❦☙ '.center(width, '–')
45
+ "#{line}\n\n#{super}\n\n#{line}"
46
+ end
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,11 @@
1
+ module Tkn2
2
+ module Utils
3
+ class << self
4
+ def strip_heredoc(string)
5
+ indent = string.scan(/^[ \t]*(?=\S)/).min
6
+ indent_level = (indent && indent.size) || 0
7
+ string.gsub(/^[ \t]{#{indent_level}}/, '')
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Tkn2
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tkn2/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tkn2"
8
+ spec.version = Tkn2::VERSION
9
+ spec.authors = ["Sergio Gil"]
10
+ spec.email = ["sgilperez@gmail.com"]
11
+ spec.description = %q{tkn2 is a terminal based presentation tool based on fxn's tkn}
12
+ spec.summary = %q{tkn2 is a terminal based presentation tool based on fxn's tkn}
13
+ spec.homepage = "https://github.com/porras/tkn2"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "pygments.rb"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tkn2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sergio Gil
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pygments.rb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: tkn2 is a terminal based presentation tool based on fxn's tkn
56
+ email:
57
+ - sgilperez@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .ruby-version
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - examples/constant_autoloading_in_ruby_on_rails.rb
69
+ - examples/simple.rb
70
+ - lib/tkn2.rb
71
+ - lib/tkn2/ansi_reader.rb
72
+ - lib/tkn2/content_block.rb
73
+ - lib/tkn2/deck.rb
74
+ - lib/tkn2/screen.rb
75
+ - lib/tkn2/slide.rb
76
+ - lib/tkn2/utils.rb
77
+ - lib/tkn2/version.rb
78
+ - tkn2.gemspec
79
+ homepage: https://github.com/porras/tkn2
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.0.3
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: tkn2 is a terminal based presentation tool based on fxn's tkn
103
+ test_files: []