preprocessor 0.1.0
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.
- 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
|