preprocessor 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/MIT-LICENSE +21 -0
- data/README.markdown +6 -0
- data/lib/preprocessor.rb +88 -0
- data/lib/preprocessor/audio.rb +14 -0
- data/lib/preprocessor/footnote.rb +37 -0
- data/lib/preprocessor/image.rb +31 -0
- data/lib/preprocessor/utilities.rb +11 -0
- data/lib/preprocessor/video.rb +56 -0
- data/preprocessor.gemspec +39 -0
- data/spec/preprocessor_spec.rb +181 -0
- data/spec/spec_helper.rb +20 -0
- metadata +91 -0
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Brandan Lennox
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
Text Preprocessor
|
2
|
+
=================
|
3
|
+
|
4
|
+
Ruby module that I use on a couple of blogs as a shortcut to reference images, audio, footnotes, etc. It's very specific to my needs, but you might find something useful in it.
|
5
|
+
|
6
|
+
I'm maintaining [the docs](http://bclennox.com/projects/preprocessor) on my site now.
|
data/lib/preprocessor.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'preprocessor/utilities'
|
2
|
+
require 'preprocessor/image'
|
3
|
+
require 'preprocessor/audio'
|
4
|
+
require 'preprocessor/video'
|
5
|
+
require 'preprocessor/footnote'
|
6
|
+
|
7
|
+
module Preprocessor
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
def preprocessed
|
11
|
+
@preprocessed ||= BasicPreprocessor.new(self)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class BasicPreprocessor
|
17
|
+
attr_accessor :delegate
|
18
|
+
|
19
|
+
include ::Preprocessor::Utilities
|
20
|
+
include ::Preprocessor::Image
|
21
|
+
include ::Preprocessor::Audio
|
22
|
+
include ::Preprocessor::Video
|
23
|
+
include ::Preprocessor::Footnote
|
24
|
+
|
25
|
+
TAG_REGEX = /(.)?\{\{(\S+?)(?:\s+(.*?))?\}\}/
|
26
|
+
REPLACEMENT_REGEX = /\{-\{-(.*?)-\}-\}/
|
27
|
+
|
28
|
+
def initialize(delegate)
|
29
|
+
self.delegate = delegate
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(sym, *args)
|
33
|
+
text = delegate.send(sym, *args)
|
34
|
+
|
35
|
+
while text.match(TAG_REGEX)
|
36
|
+
text.sub!(TAG_REGEX, replacement_for($2, $3, $1 || ''))
|
37
|
+
end
|
38
|
+
|
39
|
+
text.gsub!(REPLACEMENT_REGEX, '{{\1}}')
|
40
|
+
text
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def replacement_for(message, options_string, antecedant)
|
46
|
+
if escape?(antecedant)
|
47
|
+
antecedant = ''
|
48
|
+
replacement = replacement_placeholder(message, options_string)
|
49
|
+
else
|
50
|
+
replacement = if respond_to?(message)
|
51
|
+
send(message, options_from_string(options_string))
|
52
|
+
elsif delegate.respond_to?(message)
|
53
|
+
delegate.send(message)
|
54
|
+
else
|
55
|
+
replacement_placeholder(message, options_string)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
antecedant + replacement
|
60
|
+
end
|
61
|
+
|
62
|
+
def replacement_placeholder(text, options)
|
63
|
+
"{-{-#{[text, options].compact.join(' ')}-}-}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def escape?(char)
|
67
|
+
char == '\\'
|
68
|
+
end
|
69
|
+
|
70
|
+
def options_from_string(options_string)
|
71
|
+
return {} if options_string.nil?
|
72
|
+
|
73
|
+
# replace strings first
|
74
|
+
re = /:(["'|])(.*?)(\1)/
|
75
|
+
string_refs = []
|
76
|
+
while options_string.match(re)
|
77
|
+
options_string.sub!(re, ":ppstringref#{string_refs.length}")
|
78
|
+
string_refs.push($2)
|
79
|
+
end
|
80
|
+
|
81
|
+
options_string.split(/\s+/).inject({}) do |memo, o|
|
82
|
+
q = o.split(/:/, 2)
|
83
|
+
memo[q.first.to_sym] = q.last.match(/ppstringref(\d+)/) ? string_refs[$1.to_i] : q.last
|
84
|
+
memo
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Preprocessor
|
2
|
+
module Audio
|
3
|
+
class << self
|
4
|
+
attr_accessor :options
|
5
|
+
end
|
6
|
+
|
7
|
+
@options = { :default_path => '/audio' }
|
8
|
+
|
9
|
+
def audio(options)
|
10
|
+
src = absolutize(options[:src], ::Preprocessor::Audio.options[:default_path])
|
11
|
+
%{<audio controls><source src="#{src}.oga" type="audio/ogg" /><source src="#{src}.mp3" type="audio/mpeg" /></audio>}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Preprocessor
|
2
|
+
module Footnote
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
attr_accessor :footnote_refs
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def footnote(options)
|
10
|
+
ref = options[:ref]
|
11
|
+
add_footnote(ref, options[:text])
|
12
|
+
|
13
|
+
id = "#{guid}-#{options[:ref]}"
|
14
|
+
%{<a href="#fn-#{id}" class="footnote" id="ref-#{id}">#{ref}</a>}
|
15
|
+
end
|
16
|
+
|
17
|
+
def footnotes(options)
|
18
|
+
footnote_refs.nil? ? "" : footnote_refs.map { |fn| footnote_content(fn) }.join
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def guid
|
24
|
+
delegate.slug
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_footnote(ref, text)
|
28
|
+
@footnote_refs ||= {}
|
29
|
+
@footnote_refs[ref] = text
|
30
|
+
end
|
31
|
+
|
32
|
+
def footnote_content(fn)
|
33
|
+
id = "#{guid}-#{fn[0]}"
|
34
|
+
%:#(#fn-#{id}) #{fn[1]} <a href="#ref-#{id}" class="returner" title="Return to where you left off">↩</a>\n:
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Preprocessor
|
2
|
+
module Image
|
3
|
+
class << self
|
4
|
+
attr_accessor :options
|
5
|
+
end
|
6
|
+
|
7
|
+
@options = { :default_path => '/images' }
|
8
|
+
|
9
|
+
def image(options)
|
10
|
+
attrs = {
|
11
|
+
:src => absolutize(options[:src], ::Preprocessor::Image.options[:default_path]),
|
12
|
+
:alt => options[:alt] || "",
|
13
|
+
:title => options[:title] == "alt" ? options[:alt] : options[:title]
|
14
|
+
}
|
15
|
+
|
16
|
+
caption_text = case options[:caption]
|
17
|
+
when "alt"
|
18
|
+
attrs[:alt]
|
19
|
+
when "title"
|
20
|
+
attrs[:title]
|
21
|
+
else
|
22
|
+
options[:caption]
|
23
|
+
end
|
24
|
+
|
25
|
+
caption = %{<span class="caption">#{caption_text}</span>}
|
26
|
+
attr_str = attrs.map { |k, v| %{#{k}="#{v}"} }.join(' ')
|
27
|
+
|
28
|
+
%{<p class="image"><img #{attr_str} />#{caption}</p>}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Preprocessor
|
2
|
+
module Video
|
3
|
+
class << self
|
4
|
+
attr_accessor :options
|
5
|
+
end
|
6
|
+
|
7
|
+
@options = { :default_path => '/video' }
|
8
|
+
|
9
|
+
class YouTube
|
10
|
+
attr_accessor :src
|
11
|
+
URL_REGEXP = /youtube\.com\/(?:watch\?v=|v\/)([^\/?&]+)/i
|
12
|
+
|
13
|
+
def initialize(options)
|
14
|
+
self.src = options[:src]
|
15
|
+
end
|
16
|
+
|
17
|
+
def tag
|
18
|
+
if src =~ URL_REGEXP
|
19
|
+
url = "http://www.youtube.com/v/#{$1}"
|
20
|
+
%{<object width="425" height="344"><param name="movie" value="#{url}"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="#{url}" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.recognizes?(src)
|
25
|
+
src =~ URL_REGEXP
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Default
|
30
|
+
attr_accessor :src, :poster
|
31
|
+
|
32
|
+
# lame
|
33
|
+
include ::Preprocessor::Utilities
|
34
|
+
|
35
|
+
def initialize(options)
|
36
|
+
self.src = options[:src]
|
37
|
+
self.poster = options[:poster]
|
38
|
+
end
|
39
|
+
|
40
|
+
def tag
|
41
|
+
src = absolutize(self.src, ::Preprocessor::Video.options[:default_path])
|
42
|
+
poster = self.poster && %{poster="#{self.poster}"}
|
43
|
+
|
44
|
+
# eventually should use http://camendesign.com/code/video_for_everybody
|
45
|
+
%{<video controls #{poster}><source src="#{src}.ogv" type="video/ogg" /><source src="#{src}.mp4" type="video/mp4" /></video>}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
CUSTOM_EMBEDDERS = [YouTube]
|
50
|
+
|
51
|
+
def video(options)
|
52
|
+
embedder = CUSTOM_EMBEDDERS.detect { |e| e.recognizes?(options[:src]) } || Default
|
53
|
+
embedder.new(options).tag
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "preprocessor/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "preprocessor"
|
7
|
+
s.version = Preprocessor::VERSION
|
8
|
+
s.authors = ["Brandan Lennox"]
|
9
|
+
s.email = ["brandan@bclennox.com"]
|
10
|
+
s.homepage = "https://github.com/bclennox/preprocessor"
|
11
|
+
s.date = "2012-01-28"
|
12
|
+
s.summary = %q{Ruby text munger}
|
13
|
+
s.description = %q{Ruby module that I use on a couple of blogs as a shortcut to reference images, audio, footnotes, etc. It's very specific to my needs, but you might find something useful in it.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "preprocessor"
|
16
|
+
|
17
|
+
s.files = %w{
|
18
|
+
preprocessor.gemspec
|
19
|
+
Gemfile
|
20
|
+
MIT-LICENSE
|
21
|
+
README.markdown
|
22
|
+
|
23
|
+
lib/preprocessor.rb
|
24
|
+
lib/preprocessor/audio.rb
|
25
|
+
lib/preprocessor/footnote.rb
|
26
|
+
lib/preprocessor/image.rb
|
27
|
+
lib/preprocessor/utilities.rb
|
28
|
+
lib/preprocessor/video.rb
|
29
|
+
}
|
30
|
+
|
31
|
+
s.test_files = %w{
|
32
|
+
spec/preprocessor_spec.rb
|
33
|
+
spec/spec_helper.rb
|
34
|
+
}
|
35
|
+
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
|
38
|
+
s.add_development_dependency "rspec"
|
39
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class PreprocessorTester
|
4
|
+
def initialize(options = {})
|
5
|
+
options.each do |message, value|
|
6
|
+
self.class.class_eval { attr_accessor message }
|
7
|
+
send("#{message}=", value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
include ::Preprocessor
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Preprocessor do
|
15
|
+
it 'should ignore escaped curlies' do
|
16
|
+
tester = PreprocessorTester.new(:name => 'Munge', :title => 'Remember my \{{name with:"a mnemonic"}}')
|
17
|
+
tester.preprocessed.title.should == 'Remember my {{name with:"a mnemonic"}}'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should substitute method return values if the delegate responds_to?' do
|
21
|
+
tester = PreprocessorTester.new(:name => 'Fooject', :title => 'This is the {{name}}')
|
22
|
+
tester.preprocessed.title.should == 'This is the Fooject'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should prioritize sub-module methods over delegate methods' do
|
26
|
+
tester = PreprocessorTester.new(:image => 'paperclip', :text => 'Look! My new Zune: {{image src:shit-brown.png}}')
|
27
|
+
tester.preprocessed.text.should_not =~ /paperclip/
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should return the unchanged string if neither it nor the delegate responds_to?' do
|
31
|
+
tester = PreprocessorTester.new(:text => "I don't understand {{anything}}")
|
32
|
+
tester.preprocessed.text.should == "I don't understand {{anything}}"
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "parsing option strings" do
|
36
|
+
before(:each) do
|
37
|
+
@tester = PreprocessorTester.new
|
38
|
+
end
|
39
|
+
|
40
|
+
def options_from_string(string)
|
41
|
+
@tester.preprocessed.send(:options_from_string, string)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should parse unquoted option values' do
|
45
|
+
options_from_string('arg:simple').should == { :arg => 'simple' }
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should parse single-quoted option values' do
|
49
|
+
options_from_string(%{arg:'Not so much "fat" as "dumb".'}).should == { :arg => 'Not so much "fat" as "dumb".' }
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should parse double-quoted option values' do
|
53
|
+
options_from_string(%{arg:"D'oh!"}).should == { :arg => "D'oh!" }
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should parse piped option values' do
|
57
|
+
options_from_string(%{arg:|And I said, "Frankly, my dear, I don't give a damn!"|}).should == { :arg => %{And I said, "Frankly, my dear, I don't give a damn!"} }
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should parse option values with special characters' do
|
61
|
+
options_from_string(%{arg:http://www.example.com/}).should == { :arg => 'http://www.example.com/' }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "utilities" do
|
66
|
+
class UtilitiesTester
|
67
|
+
include ::Preprocessor::Utilities
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should ignore absolute paths' do
|
71
|
+
UtilitiesTester.new.absolutize('/my/stuff/me.png', '/where/ever').should == '/my/stuff/me.png'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should not prepend the default path to URLs' do
|
75
|
+
UtilitiesTester.new.absolutize('http://example.com/illicit.png', '/lalala').should == 'http://example.com/illicit.png'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#image" do
|
80
|
+
it 'should have src, alt, title attributes and a caption' do
|
81
|
+
tester = PreprocessorTester.new(:text => 'This chick is mad hot: {{image src:chick.png alt:"Chicken in the oven" title:"No title necessary" caption:"Look how hot yah"}}')
|
82
|
+
tester.preprocessed.text.should =~ /src="\/images\/chick.png"/
|
83
|
+
tester.preprocessed.text.should =~ /alt="Chicken in the oven"/
|
84
|
+
tester.preprocessed.text.should =~ /title="No title necessary"/
|
85
|
+
tester.preprocessed.text.should =~ /Look how hot yah/
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should allow shortcutting title and caption' do
|
89
|
+
tester = PreprocessorTester.new(:text => 'Lazy {{image src:foo.png alt:"Required" title:alt caption:title}}')
|
90
|
+
tester.preprocessed.text.should =~ /title="Required"/
|
91
|
+
tester.preprocessed.text.should =~ /<span class="caption">Required<\/span>/
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should set the default path' do
|
95
|
+
::Preprocessor::Image.options[:default_path] = '/system/assets'
|
96
|
+
tester = PreprocessorTester.new(:text => 'Hope it works: {{image src:boo.png alt:"Whatevs"}}')
|
97
|
+
tester.preprocessed.text.should =~ /src="\/system\/assets\/boo.png"/
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#audio" do
|
102
|
+
before(:each) do
|
103
|
+
@tester = PreprocessorTester.new(:text => 'Peep this sweet cut: {{audio src:piano-rock}}')
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should contain a source for the MP3 file' do
|
107
|
+
@tester.preprocessed.text.should =~ /piano-rock.mp3/
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should contain a source for the Ogg file' do
|
111
|
+
@tester.preprocessed.text.should =~ /piano-rock.oga/
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should set the default path' do
|
115
|
+
::Preprocessor::Audio.options[:default_path] = '/somewhere/else'
|
116
|
+
@tester.preprocessed.text.should =~ /\/somewhere\/else\/piano-rock/
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should not prepend the default path to absolute paths' do
|
120
|
+
tester = PreprocessorTester.new(:text => 'Baddies: {{audio src:/i/love/bob}}')
|
121
|
+
tester.preprocessed.text.should =~ /\/i\/love\/bob/
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#video" do
|
126
|
+
describe 'YouTube videos' do
|
127
|
+
it 'should recognize a "watch" URL with a query string' do
|
128
|
+
::Preprocessor::Video::YouTube.should recognize('http://www.youtube.com/watch?v=jHyC0ggI3Ow&feature=player_embedded')
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should recognize a "/v/" URL with a query string' do
|
132
|
+
::Preprocessor::Video::YouTube.should recognize('http://www.youtube.com/v/jHyC0ggI3Ow&hl=en_US&fs=1&rel=0')
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should include the object and embed shit' do
|
136
|
+
tester = PreprocessorTester.new(:text => 'LOLOL {{video src:"http://www.youtube.com/watch?v=jHyC0ggI3Ow"}}')
|
137
|
+
tester.preprocessed.text.should =~ /param name="movie" value="http:\/\/www.youtube.com\/v\/jHyC0ggI3Ow"/
|
138
|
+
tester.preprocessed.text.should =~ /embed src="http:\/\/www.youtube.com\/v\/jHyC0ggI3Ow"/
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "HTML 5 videos" do
|
143
|
+
it 'should include the MP4 source' do
|
144
|
+
tester = PreprocessorTester.new(:text => '{{video src:/videos/dancedancedance}}')
|
145
|
+
tester.preprocessed.text.should =~ /dancedancedance.mp4/
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should include the Ogg source' do
|
149
|
+
tester = PreprocessorTester.new(:text => '{{video src:/videos/ooouuuuttttt}}')
|
150
|
+
tester.preprocessed.text.should =~ /ooouuuuttttt.ogv/
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should include an optional poster' do
|
154
|
+
tester = PreprocessorTester.new(:text => '{{video src:/videos/help poster:/images/posse.png}}')
|
155
|
+
tester.preprocessed.text.should =~ /poster="\/images\/posse.png"/
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "#footnote" do
|
161
|
+
before(:each) do
|
162
|
+
@tester = PreprocessorTester.new(:text => 'Surprised kitten is surprised.{{footnote ref:1 text:"Not for resale."}} Some more content{{footnote ref:2 text:"Is there more?"}} haha. Content sucks. {{footnotes}}', :slug => 'slug-boat')
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should contain reference links' do
|
166
|
+
[1, 2].each do |i|
|
167
|
+
@tester.preprocessed.text.should =~ /<a href="#fn-slug-boat-#{i}".*id="ref-slug-boat-#{i}".*?>#{i}/
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should contain the footnotes in a Textile list' do
|
172
|
+
@tester.preprocessed.text.should =~ /#\(#fn-slug-boat-1\)\s+Not for resale./
|
173
|
+
@tester.preprocessed.text.should =~ /#\(#fn-slug-boat-2\)\s+Is there more?/
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should not explode if {{footnotes}} is called without any footnotes' do
|
177
|
+
tester = PreprocessorTester.new(:text => 'There are no {{footnotes}}.')
|
178
|
+
tester.preprocessed.text.should == 'There are no .'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'preprocessor')
|
2
|
+
|
3
|
+
# for video embedders
|
4
|
+
RSpec::Matchers.define :recognize do |src|
|
5
|
+
match do |embedder|
|
6
|
+
embedder.recognizes?(src)
|
7
|
+
end
|
8
|
+
|
9
|
+
failure_message_for_should do |embedder|
|
10
|
+
"#{embedder} should recognize #{src} and doesn't"
|
11
|
+
end
|
12
|
+
|
13
|
+
failure_message_for_should_not do |embedder|
|
14
|
+
"#{embedder} should not recognize #{src} and does"
|
15
|
+
end
|
16
|
+
|
17
|
+
description do
|
18
|
+
"whatever"
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: preprocessor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Brandan Lennox
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-28 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Ruby module that I use on a couple of blogs as a shortcut to reference images, audio, footnotes, etc. It's very specific to my needs, but you might find something useful in it.
|
35
|
+
email:
|
36
|
+
- brandan@bclennox.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- preprocessor.gemspec
|
45
|
+
- Gemfile
|
46
|
+
- MIT-LICENSE
|
47
|
+
- README.markdown
|
48
|
+
- lib/preprocessor.rb
|
49
|
+
- lib/preprocessor/audio.rb
|
50
|
+
- lib/preprocessor/footnote.rb
|
51
|
+
- lib/preprocessor/image.rb
|
52
|
+
- lib/preprocessor/utilities.rb
|
53
|
+
- lib/preprocessor/video.rb
|
54
|
+
- spec/preprocessor_spec.rb
|
55
|
+
- spec/spec_helper.rb
|
56
|
+
homepage: https://github.com/bclennox/preprocessor
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: preprocessor
|
85
|
+
rubygems_version: 1.8.15
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Ruby text munger
|
89
|
+
test_files:
|
90
|
+
- spec/preprocessor_spec.rb
|
91
|
+
- spec/spec_helper.rb
|