texttube_baby 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 418cb4a5268b6c0f2e97adadcd5f98ead13fb5ab
4
+ data.tar.gz: f767767cd2ab6c8800717fb87af479bc3db01f2c
5
+ SHA512:
6
+ metadata.gz: 4abc064a958b26c54291288ac0c89d41ff7ebabee88ce5abb0ff7ec32fb60d74f0a7742683fead1b078f2f402016a873e9d7443fc482c998d2cb768cbf2ddc24
7
+ data.tar.gz: b2aa89e936d22a0153e31770777ad88024925fdb29fe473703e219b3ab2ae951f5f821125986574f74c171770e030f966a7d09951d9a9104d868b7f1e6a64b82
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.old
2
+ *.tmproj
3
+ .DS_Store
4
+ .rvmrc
5
+
6
+ *.gem
7
+
8
+ *.7z
9
+ *.dmg
10
+ *.gz
11
+ *.iso
12
+ *.jar
13
+ *.rar
14
+ *.tar
15
+ *.zip
16
+ pkg
17
+ rdoc
18
+ .rspec
19
+ Gemfile.lock
20
+ bin/
21
+ vendor/
22
+ coverage/
23
+ docs/
24
+ .yardoc/
25
+ .bundle/
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in TextTubeBaby.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem "rspec"
8
+ gem "simplecov"
9
+ end
data/LICENCE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Iain Barnett
2
+
3
+ MIT Licence
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.
data/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # TextTubeBaby
2
+
3
+ Here are some ready built filters to use with TextTube. If you write any you think would be useful, send me a pull request!
4
+
5
+ ### Note! ###
6
+
7
+ If you're having a problem with the TextTube::InsideBlock filter on Heroku it could be because of the version of Libxml2 it uses, as [the problem given here states](http://stackoverflow.com/q/8598958/335847), which means Nokogiri won't always work properly on Heroku. When using the InsideBlock filter this can be a problem, so use the `hpricot` branch instead.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'texttube_baby'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install texttube_baby
24
+
25
+ ## The Filters! ##
26
+
27
+ ### LinkReffing ###
28
+
29
+ If you'd don't want your links inline and would prefer to have them at the bottom of the document, then you can use this:
30
+
31
+ require 'texttube/base'
32
+ require 'texttube/baby/link_reffing'
33
+
34
+ class TextWithLinks < TextTube::Base
35
+ register TextTube::Baby::LinkReffing
36
+ end
37
+
38
+ s = TextWithLinks.new %q!Iain's blog[[http://iainbarnett.me.uk|My blog]] is good. Erik Hollensbe's blog[[http://erik.hollensbe.org/|Holistic Engineering]] is also good, as is James Coglan's blog[[http://blog.jcoglan.com/|The If Works]]!
39
+
40
+ s.filter
41
+
42
+ and it will produce this:
43
+
44
+ # => "Iain's blog[&#8304;](#0 "Jump to reference") is good. Erik Hollensbe's blog[&sup1;](#1 "Jump to reference") is also good, as is James Coglan's blog[&sup2;](#2 "Jump to reference")\n<div markdown='1' id='reflinks'>\n<a name="0"></a>&#91;0&#93; [http://iainbarnett.me.uk](http://iainbarnett.me.uk "http://iainbarnett.me.uk") My blog\n\n\n<a name="1"></a>&#91;1&#93; [http://erik.hollensbe.org/](http://erik.hollensbe.org/ "http://erik.hollensbe.org/") Holistic Engineering\n\n\n<a name="2"></a>&#91;2&#93; [http://blog.jcoglan.com/](http://blog.jcoglan.com/ "http://blog.jcoglan.com/") The If Works\n\n</div>"
45
+
46
+ Run that through a markdown parser and you get:
47
+
48
+ <p>Iain's blog<a href="#0" title="Jump to reference">&#8304;</a> is good. Erik Hollensbe's blog<a href="#1" title="Jump to reference">&sup1;</a> is also good, as is James Coglan's blog<a href="#2" title="Jump to reference">&sup2;</a></p>
49
+
50
+ <div markdown='1' id='reflinks'>
51
+ <a name="0"></a>&#91;0&#93; [http://iainbarnett.me.uk](http://iainbarnett.me.uk "http://iainbarnett.me.uk") My blog
52
+
53
+
54
+ <a name="1"></a>&#91;1&#93; [http://erik.hollensbe.org/](http://erik.hollensbe.org/ "http://erik.hollensbe.org/") Holistic Engineering
55
+
56
+
57
+ <a name="2"></a>&#91;2&#93; [http://blog.jcoglan.com/](http://blog.jcoglan.com/ "http://blog.jcoglan.com/") The If Works
58
+
59
+ </div>
60
+
61
+ Using this will probably end up with also using InsideBlock, to transform the markdown inside the div.
62
+
63
+ ### InsideBlock ###
64
+
65
+ Sometimes it'd be useful to wrap some markdown with HTML, for example:
66
+
67
+ <div id="notes">
68
+
69
+ * first
70
+ * second
71
+ * third
72
+
73
+ </div>
74
+
75
+ If you put this through a markdown parser the markdown won't get parsed:
76
+
77
+ require 'rdiscount'
78
+ s = "<div id="notes">\n\n* first\n* second\n* third\n\n</div>\n"
79
+ puts RDiscount.new(s).to_html
80
+
81
+ This is the output:
82
+
83
+ <div id="notes">
84
+
85
+ * first
86
+ * second
87
+ * third
88
+
89
+ </div>
90
+
91
+ My brilliant idea to get around this is to add an HTML attribute of `markdown='1'` to HTML tags that you want the markdown parser to look inside:
92
+
93
+ <div id="notes" markdown='1'>
94
+
95
+ * first
96
+ * second
97
+ * third
98
+
99
+ </div>
100
+
101
+ Trying this with `InsideBlock` gives:
102
+
103
+ puts TextTube::Baby::InsideBlock.run s
104
+
105
+ <div id="notes">
106
+ <ul>
107
+ <li>first</li>
108
+ <li>second</li>
109
+ <li>third</li>
110
+ </ul>
111
+
112
+ </div>
113
+
114
+ To use it as a filter:
115
+
116
+ require 'texttube/base'
117
+
118
+ class MyFilter < TextTube::Baby::Base
119
+ register TextTube::Baby::InsideBlock
120
+ end
121
+
122
+ myf = MyFilter.new(s)
123
+ # => "<div id="notes" markdown='1'>\n\n* first\n* second\n* third\n\n</div>\n"
124
+
125
+ puts myf.filter
126
+
127
+ Gives:
128
+
129
+ <div id="notes">
130
+ <ul>
131
+ <li>first</li>
132
+ <li>second</li>
133
+ <li>third</li>
134
+ </ul>
135
+
136
+ </div>
137
+
138
+ ### Coderay ###
139
+
140
+ Filters an HTML code block and marks it up with [coderay](http://coderay.rubychan.de/):
141
+
142
+
143
+
144
+ require 'texttube/base'
145
+ require 'texttube/baby/coderay'
146
+ require 'rdiscount' # a markdown parser
147
+
148
+ class TextWithCode < TextTube::Baby::Base
149
+ register do
150
+ filter_with :rdiscount do |text|
151
+ RDiscount.new(text).to_html
152
+ end
153
+ end
154
+ register TextTube::Baby::Coderay
155
+ end
156
+
157
+ s = TextWithCode.new <<'STR'
158
+ # FizzBuzz #
159
+
160
+ ::::ruby
161
+ (1..100).each do |n|
162
+ out = "#{n}: "
163
+ out << "Fizz" if n % 3 == 0
164
+ out << "Buzz" if n % 5 == 0
165
+ puts out
166
+ end
167
+
168
+ That's all folks!
169
+ STR
170
+ # => "# FizzBuzz #\n\n ::::ruby\n (1..100).each do |n| \n out = "\#{n}: "\n out << "Fizz" if n % 3 == 0\n out << "Buzz" if n % 5 == 0\n puts out\n end\n\nThat's all folks!\n"
171
+
172
+
173
+ puts s.filter
174
+
175
+ Produces:
176
+
177
+ <h1>FizzBuzz</h1>
178
+
179
+ <pre><code class="CodeRay">(<span class="integer">1</span>..<span class="integer">100</span>).each <span class="keyword">do</span> |n|
180
+ out = <span class="string"><span class="delimiter">"</span><span class="inline"><span class="inline-delimiter">#{</span>n<span class="inline-delimiter">}</span></span><span class="content">: </span><span class="delimiter">"</span></span>
181
+ out &lt;&lt; <span class="string"><span class="delimiter">"</span><span class="content">Fizz</span><span class="delimiter">"</span></span> <span class="keyword">if</span> n % <span class="integer">3</span> == <span class="integer">0</span>
182
+ out &lt;&lt; <span class="string"><span class="delimiter">"</span><span class="content">Buzz</span><span class="delimiter">"</span></span> <span class="keyword">if</span> n % <span class="integer">5</span> == <span class="integer">0</span>
183
+ puts out
184
+ <span class="keyword">end</span></code></pre>
185
+
186
+ <p>That's all folks!</p>
187
+
188
+ The language was specified with a leading `::::ruby`. It didn't have to be as the default is to use Ruby, but if you want to use any other of the [coderay supported languages](http://coderay.rubychan.de/doc/CodeRay/Scanners.html), that's how to do it.
189
+
190
+ ### Spiffing ###
191
+
192
+ Transforms CSS written in British English into its ugly sister from across the pond. Inspired by [visualidiot's SpiffingCSS](https://github.com/visualidiot/Spiffing).
193
+
194
+ content = <<CSS
195
+ body {
196
+ background-colour: darkgrey;
197
+ background-photograph: url(logo.gif);
198
+ transparency: .7;
199
+
200
+ font: 72px "Comic Sans", cursive !please;
201
+ font-weight: plump;
202
+ p { text-align: centre }
203
+ fieldset input {
204
+ text-transform: capitalise;
205
+ }
206
+ }
207
+ CSS
208
+
209
+ require 'texttube/base'
210
+ require 'texttube/baby/spiffing'
211
+
212
+ class CssString < TextTube::Base
213
+ register TextTube::Baby::Spiffing
214
+ end
215
+
216
+ puts CssString.new(content).filter
217
+
218
+ # output:
219
+
220
+ body {
221
+ background-color: darkgray;
222
+ background-image: url(logo.gif);
223
+ opacity: .7;
224
+
225
+ font: 72px "Comic Sans", cursive !important;
226
+ font-weight: bold;
227
+ p { text-align: center }
228
+ fieldset input {
229
+ text-transform: capitalize;
230
+ }
231
+ }
232
+
233
+ God save the Queen!
234
+
235
+
236
+ ## Contributing
237
+
238
+ 1. Fork it ( https://github.com/[my-github-username]/TextTubeBaby/fork )
239
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
240
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
241
+ 4. Push to the branch (`git push origin my-new-feature`)
242
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/lib/ext/blank.rb ADDED
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ module TextTube
4
+ module CoreExtensions
5
+
6
+ def blank?
7
+ respond_to?(:empty?) ?
8
+ empty? :
9
+ !self
10
+ end
11
+ end
12
+
13
+ class String < ::String
14
+ include CoreExtensions
15
+ end
16
+ end
17
+
18
+ # Standard lib class.
19
+ class Hash
20
+ include TextTube::CoreExtensions
21
+ end
@@ -0,0 +1,5 @@
1
+ module TextTube
2
+ module Baby
3
+ # Your code goes here...
4
+ end
5
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: UTF-8
2
+ module TextTube
3
+
4
+ require 'nokogiri'
5
+ require_relative "../../ext/blank.rb"
6
+ require 'coderay'
7
+ require "texttube/filterable"
8
+
9
+ # a filter for Coderay
10
+ module Coderay
11
+ extend Filterable
12
+
13
+ filter_with :coderay do |text|
14
+ TextTube::Coderay.run text
15
+ end
16
+
17
+
18
+ # @param [String] content
19
+ # @param [Hash] options
20
+ # @return [String]
21
+ def self.run(content, options={})
22
+ options = {lang: :ruby } if options.blank?
23
+ doc = Nokogiri::HTML::fragment(content)
24
+
25
+ code_blocks = doc.xpath("pre/code").map do |code_block|
26
+ #un-escape as Coderay will escape it again
27
+ inner_html = code_block.inner_html
28
+
29
+ # following the convention of Rack::Codehighlighter
30
+ if inner_html.start_with?("::::")
31
+ lines = inner_html.split("\n")
32
+ options[:lang] = lines.shift.match(%r{::::(\w+)})[1].to_sym
33
+ inner_html = lines.join("\n")
34
+ end
35
+
36
+ if (options[:lang] == :skip) || (! options.has_key? :lang )
37
+ code_block.inner_html = inner_html
38
+ else
39
+ code = Coderay.codify(Coderay.html_unescape(inner_html), options[:lang])
40
+ code_block.inner_html = code
41
+ code_block["class"] = "CodeRay"
42
+ end
43
+ end#block
44
+
45
+ doc.to_s
46
+ end#def
47
+
48
+ # @private
49
+ # Unescape the HTML as the Coderay scanner won't work otherwise.
50
+ def self.html_unescape(a_string)
51
+ a_string.gsub('&amp;', '&').gsub('&lt;', '<').gsub('&gt;',
52
+ '>').gsub('&quot;', '"')
53
+ end#def
54
+
55
+ # Run the Coderay scanner.
56
+ # @private
57
+ # @param [String] str
58
+ # @param [String] lang
59
+ # @example
60
+ # self.class.codify "x = 2", "ruby"
61
+ def self.codify(str, lang)
62
+ CodeRay.scan(str, lang).html
63
+ end#def
64
+
65
+ end#class
66
+
67
+
68
+ end#module
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+ require "texttube/filterable"
3
+
4
+ module TextTube
5
+ module Baby
6
+ # Embed some audio via [audio[link|name]]
7
+ module EmbeddingAudio
8
+ extend TextTube::Filterable
9
+
10
+ filter_with :embeddingaudio do |text|
11
+ run text
12
+ end
13
+
14
+ # default attributes
15
+ DEFAULTS = {
16
+ src_base: "/streams/",
17
+ preload: "metadata",
18
+ fallback_text: "Your browser does not support HTML5, update your browser you fool!",
19
+ controls: "controls",
20
+ }
21
+
22
+ # [audio[link|name]]
23
+ R_link = / # [audio[url|description]]
24
+ \[audio\[ # opening square brackets
25
+ ([^\|]+) # link
26
+ \| # separator
27
+ ([^\[]+) # description
28
+ \]\] # closing square brackets
29
+ /x
30
+
31
+
32
+ # @param [String] content
33
+ # @param [Hash] options
34
+ # @return [String]
35
+ def self.run(content, options={})
36
+ options ||= {}
37
+ attributes = DEFAULTS.merge options
38
+
39
+ content.gsub( R_link ) { |m|
40
+ url,desc = $1,$2
41
+ EmbeddingAudio::render_tag(url,desc,attributes)
42
+ }
43
+ end
44
+
45
+
46
+ # Does the grunt work of rendering the tag.
47
+ # @private
48
+ # @param [String] link
49
+ # @param [String] desc
50
+ # @param [Hash] attributes
51
+ def self.render_tag(link,desc,attributes)
52
+ fallback_text = attributes.delete(:fallback_text)
53
+ src_base = attributes.delete(:src_base)
54
+ make_inner = ->(lnk){%Q!<source src='#{src_base}#{lnk}' type='audio/#{File.extname(lnk)[1..-1]}' />!}
55
+ inner = make_inner.( link )
56
+ inner += make_inner.( link.sub(/m4a$/, "ogg") ) if File.extname(link) == ".m4a"
57
+ %Q!<div class='audio'><h3>#{desc}</h3><audio #{attributes.map{|(k,v)| "#{k}='#{v}'" }.join(" ")}>#{inner}#{fallback_text}</audio></div>!.strip.gsub /\s+/, " "
58
+ end
59
+
60
+ end # class
61
+ end
62
+ end # module