ruby-shortcodes 0.0.18

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
+ SHA256:
3
+ metadata.gz: 5a12ee03c9450b72520304ba08bd79e3e1208894fa2f05aa85f1c93532de45c4
4
+ data.tar.gz: 21deb3f3b42687d9c9909ee7dfbc384ec8c9462547b7edba49d4e243449028b7
5
+ SHA512:
6
+ metadata.gz: 77f08407d13f2164bb4e9c53c17735c6a14f749224db1f45466764165fba9bdf8e0875e943ba68cf556838ead15ecc75785aad0ea6572814063939cba657918b
7
+ data.tar.gz: d289ae34f8663272db408f81fb9b22f164cd8c80b17aff939f1d26068acc9f13045fe33bb64b90dc8a046a73488b05845a17197586167d717f0f0f1e513f3c60
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .DS_Store
4
+ **/.DS_Store
5
+ .bundle
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ruby-shortcodes.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 David Lee
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.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Shortcodes for Ruby
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'ruby-shortcodes'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ruby-shortcodes
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
data/lib/shortcodes.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "shortcodes/version"
2
+ require "shortcodes/wordpress_shortcodes"
3
+ require "shortcodes/tuts_shortcodes"
4
+
5
+ module Shortcodes
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,213 @@
1
+ module Shortcodes
2
+ class TutsShortcodes < WordpressShortcodes
3
+
4
+ SUPPORTED_SYNTAXES = %w(
5
+ as3 actionscript3
6
+ bash shell
7
+ cf coldfusion
8
+ c-sharp csharp
9
+ cpp c
10
+ objc obj-c
11
+ css
12
+ delphi pas pascal
13
+ diff patch
14
+ erl erlang
15
+ groovy
16
+ js jscript javascript
17
+ java
18
+ jfx javafx
19
+ perl pl
20
+ php
21
+ plain text
22
+ ps powershell
23
+ py python
24
+ rails ror ruby rb
25
+ scala
26
+ sql
27
+ vb vbnet
28
+ xml xhtml xslt html xhtml
29
+ )
30
+
31
+ def initialize
32
+ super
33
+
34
+ add_shortcode 'sessions_post' do |att|
35
+ att = {
36
+ 'href' => 'http://sessions.tutsplus.com/creative/',
37
+ 'title' => 'Creative Sessions',
38
+ 'day' => '1',
39
+ 'prev' => '',
40
+ 'next' => ''
41
+ }.merge att
42
+
43
+ navigation = ''
44
+
45
+ if att['prev'].present? || att['next'].present?
46
+ p = att['prev'].present? ? '<a href="' + att['prev'] + '" class="left">&laquo; Session Day ' + (att['day'].to_i - 1).to_s + '</a>' : ''
47
+ n = att['next'].present? ? '<a href="' + att['next'] + '" class="right">Session Day ' + (att['day'].to_i + 1).to_s + ' &raquo;</a>' : ''
48
+ navigation = '<div class="session_navigation" style="overflow:hidden;clear:both;padding-top:10px;">' + p + n + '</div>'
49
+ end
50
+
51
+ '<div class="sessions_post">This Post is Day ' + att['day'] + ' of our <a href="' + att['href'] + '">' + att['title'] + ' Session</a>. <a href="http://sessions.tutsplus.com/creative/" class="cs_span">Creative Sessions</a>' + navigation + '</div>'
52
+ end
53
+
54
+ add_shortcode 'sponsored_review' do
55
+ '<div class="review-shortcode"><strong>Sponsored Content</strong><p>This is a sponsored review or giveaway of a product/service that\'s particularly relevant to our readers.</p></div>'
56
+ end
57
+
58
+ add_shortcode 'sponsored_content' do |attr, content|
59
+ '<div class="sponsored-shortcode"><strong>Sponsored Content</strong><p>This content was commissioned by ' + content.strip + ' and was written and/or edited by the Tuts+ team. Our aim with sponsored content is to publish relevant and objective tutorials, case studies, and inspirational interviews that offer genuine educational value to our readers and enable us to fund the creation of more useful content.</p></div>'
60
+ end
61
+
62
+ add_shortcode 'disclaimer' do
63
+ '<div class="disclaimer-shortcode"><strong>Disclaimer</strong><p>You should always seek independent financial advice and thoroughly read terms and conditions relating to any insurance, tax, legal, or financial issue, service, or product. This article is intended as a guide only.</p></div>'
64
+ end
65
+
66
+ add_shortcode 'republished' do |attr, content|
67
+ '<div class="republished-shortcode"><strong>Republished Tutorial</strong><p>Every few weeks, we revisit some of our reader\'s favorite posts from throughout the history of the site. This tutorial was first published in ' + content + '.</p></div>'
68
+ end
69
+
70
+ add_shortcode 'changed' do |attr, content|
71
+ '<div class="changed-shortcode"><strong>Subsequent Changes to Techniques &amp; Software</strong><p>Certain aspects of applications or techniques used in this tutorial have changed since it was originally published. This might make it a little difficult to follow along. We\'d recommend looking at these more recent tutorials on the same topic:</p>' + content + '</div>'
72
+ end
73
+
74
+ add_shortcode 'videodownload' do |attr, content|
75
+ '<div class="videodownload-shortcode"><strong>Download Video</strong>' + content + '</div>'
76
+ end
77
+
78
+ add_shortcode 'tip' do |attr, content|
79
+ if content
80
+ '<div class="tip-shortcode">' + content + '</div>';
81
+ else
82
+ ''
83
+ end
84
+ end
85
+
86
+ add_shortcode 'related' do |attr, content|
87
+ '<div class="related-shortcode"><strong>Related Posts</strong>' + content + '</div>';
88
+ end
89
+
90
+ add_shortcode 'audio' do |att|
91
+ if att.respond_to? :last
92
+ att.delete(":")
93
+ audio_url = att.join(' ').gsub(/^:/, '')
94
+ type = nil
95
+ else
96
+ audio_url = att.values.last
97
+ codec = att.keys.first
98
+ type = case codec
99
+ when 'mp3'
100
+ %Q[type='audio/mpeg; codecs="mp3"']
101
+ when 'ogg','vorbis'
102
+ %Q[type='audio/ogg; codecs="vorbis"']
103
+ else
104
+ nil
105
+ end
106
+ end
107
+ %Q[<audio src="#{audio_url}" #{type} />]
108
+ end
109
+
110
+ add_shortcode 'mathjax' do
111
+ '<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>'
112
+ end
113
+
114
+ handle_sourcecode = Proc.new do |att, content|
115
+ att = { 'language' => 'plain' } unless att.is_a?(Hash) # Use plain as the default
116
+
117
+ att['brush'] = att.delete('language') || att.delete('lang')
118
+ attrs = att.map do |k,v|
119
+ v = "[#{v}]" if k == 'highlight'
120
+ "#{k}: #{v}"
121
+ end.join('; ')
122
+
123
+ if content
124
+ # Not left-stripping content because we want to preserve any indentations
125
+ # at the start.
126
+ %(<pre class="#{attrs}">#{content.rstrip}</pre>)
127
+ else
128
+ ''
129
+ end
130
+ end
131
+
132
+ add_shortcode 'sourcecode', &handle_sourcecode
133
+ add_shortcode 'code', &handle_sourcecode
134
+
135
+ SUPPORTED_SYNTAXES.each do |lang|
136
+ add_shortcode lang do |att, content|
137
+ new_att = { 'language' => lang }
138
+ new_att.merge!(att) if att.is_a? Hash
139
+ handle_sourcecode.call(new_att, content)
140
+ end
141
+ end
142
+
143
+ add_shortcode 'quiz' do |att|
144
+ '<div id="quiz-container" style="margin-bottom: 30px;"></div>
145
+ <link rel="stylesheet" href="http://nettuts.s3.amazonaws.com/jquizzy-1.0/css/styles-cloud-version1.30.css" />
146
+ <script src="http://nettuts.s3.amazonaws.com/jquizzy-1.0/js/jquery.jquizzyv1.35.js"></script>
147
+ <script src="' + att['url'] + '"></script>
148
+
149
+ <script>
150
+ function initQuiz() {
151
+ if (window.init) {
152
+ $("#quiz-container").jquizzy({
153
+ questions: init.questions,
154
+ resultComments: init.resultComments,
155
+ twitterStatus: "Woo! I got {score} on the @envatopsd quiz. Try it! http://bit.ly/linky",
156
+ twitterUsername: "envatopsd",
157
+ twitterImage: "http://nettuts.s3.amazonaws.com/jquizzy-1.0/img/share.png",
158
+ splashImage: "' + att['image'] + '"
159
+ });
160
+ } else {
161
+ setTimeout(initQuiz, 100);
162
+ }
163
+ }
164
+ $(document).ready(function() { initQuiz() });
165
+ </script>'
166
+ end
167
+
168
+ add_shortcode 'polldaddy' do |att|
169
+ %(<script type="text/javascript" charset="utf-8" src="http://static.polldaddy.com/p/#{att['id']}.js"></script>)
170
+ end
171
+
172
+ add_shortcode 'WP_UnityObject' do |att|
173
+ # The WP plugin generates an iframe tag to load another php script that embeds the actual content with some JS.
174
+ # To makes things simpler for us, we're going to load the object in place using this method instead (loosely):
175
+ # http://docs.unity3d.com/Documentation/Manual/HTMLcodetoloadUnityWebPlayercontent.html
176
+ #
177
+ # TODO: allow more than one of this in the same page.
178
+ #
179
+ # TODO: (less urgent) load the js from https://ssl-webplayer... when on SSL, could've used '//webplayer.unity3d.com'
180
+ # if unity3d were smarter :/
181
+ %Q{
182
+ <script src="http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject2.js"></script>
183
+ <script async>$(function(){new UnityObject2().initPlugin($('.unity-player')[0], "#{att['src']}");});</script>
184
+ <div class="unity-player" style="width:#{att['width']}px;height:#{att['height']}px">
185
+ <div class="unity-player__missing">
186
+ <a href="http://unity3d.com/webplayer/">
187
+ <img alt="Unity Web Player. Install now!" src="http://webplayer.unity3d.com/installation/getunity.png" width="193" height="63" />
188
+ </a>
189
+ </div>
190
+ </div>
191
+ }.gsub(/\s+/, ' ').gsub(/>\s+</, '><').strip
192
+ end
193
+
194
+ add_shortcode 'caption' do |att, content|
195
+ if match = content.match(/^\s*(<img[^>]*>)\s*(.*)$/)
196
+ %(<figure class="post_image">#{match[1]}<figcaption>#{match[2]}</figcaption></figure>)
197
+ else
198
+ content
199
+ end
200
+ end
201
+
202
+ add_shortcode 'player' do |att|
203
+ if src = att['href']
204
+ width = att['width'] || "100%"
205
+ height = att['height'] || "auto"
206
+ %Q{
207
+ <video class="post__content-video" src="#{src}" width="#{width}" height="#{height}" />
208
+ }.strip
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,3 @@
1
+ module Shortcodes
2
+ VERSION = "0.0.18"
3
+ end
@@ -0,0 +1,123 @@
1
+ require 'active_support/core_ext/object'
2
+ module Shortcodes
3
+ class WordpressShortcodes
4
+ # Ruby port of WordPress wp-includes/shortcodes
5
+
6
+ def initialize
7
+ @shortcode_tags = {}
8
+ end
9
+
10
+ def process(html)
11
+ if @shortcode_tags.any?
12
+ html.gsub(get_shortcode_regex){ do_shortcode_tag *($~.to_a) }
13
+ else
14
+ html
15
+ end
16
+ end
17
+
18
+ def add_shortcode(tag, &block)
19
+ @shortcode_tags[tag] = block
20
+ end
21
+
22
+ def remove_shortcode(tag)
23
+ @shortcode_tags.delete tag
24
+ end
25
+
26
+ def get_shortcode_regex
27
+ tagnames = @shortcode_tags.keys
28
+ tagregexp = tagnames.map{ |x| Regexp::quote(x) }.join('|')
29
+
30
+ Regexp.new('\[' + # Opening bracket
31
+ '(\[?)' + # 1: Optional second opening bracket for escaping shortcodes: [[tag]]
32
+ "(#{tagregexp})" + # 2: Shortcode name
33
+ '\b' + # Word boundary
34
+ '(' + # 3: Unroll the loop: Inside the opening shortcode tag
35
+ '[^\]\/]*' + # Not a closing bracket or forward slash
36
+ '(?:' +
37
+ '\/(?!\])' + # A forward slash not followed by a closing bracket
38
+ '[^\]\/]*' + # Not a closing bracket or forward slash
39
+ ')*?' +
40
+ ')' +
41
+ '(?:' +
42
+ '(\/)' + # 4: Self closing tag ...
43
+ '\]' + # ... and closing bracket
44
+ '|' +
45
+ '\]' + # Closing bracket
46
+ '(?:' +
47
+ '(' + # 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
48
+ '[^\[]*+' + # Not an opening bracket
49
+ '(?:' +
50
+ '\[(?!\/\2\])' + # An opening bracket not followed by the closing shortcode tag
51
+ '[^\[]*+' + # Not an opening bracket
52
+ ')*+' +
53
+ ')' +
54
+ '\[\/\2\]' + # Closing shortcode tag
55
+ ')?' +
56
+ ')' +
57
+ '(\]?)' # 6: Optional second closing brocket for escaping shortcodes: [[tag]]
58
+ )
59
+ end
60
+
61
+ def do_shortcode_tag(*m)
62
+ # allow [[foo]] syntax for escaping a tag
63
+ return m[0][1..-2] if m[1] == '[' && m[6] == ']'
64
+
65
+ tag = m[2]
66
+ att = shortcode_parse_atts m[3]
67
+
68
+ if m[5].present?
69
+ # enclosing tag - extra parameter
70
+ m[1] + @shortcode_tags[tag].call(att, m[5], tag) + m[6]
71
+ else
72
+ # self-closing tag
73
+ m[1] + @shortcode_tags[tag].call(att, nil, tag) + m[6]
74
+ end
75
+ end
76
+
77
+ def shortcode_parse_atts(text)
78
+ pattern = /(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*'([^']*)'(?:\s|$)|(\w+)\s*=\s*([^\s'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/
79
+ text = text.gsub /[\u{00a0}\u{200b}]+/, ' '
80
+
81
+ att_hash = {}
82
+ att_array = []
83
+ text.scan(pattern) do |m1, m2, m3, m4, m5, m6, m7, m8|
84
+ if m1.present?
85
+ att_hash[m1.downcase] = m2
86
+ elsif m3.present?
87
+ att_hash[m3.downcase] = m4
88
+ elsif m5.present?
89
+ att_hash[m5] = m6
90
+ elsif m7.present?
91
+ att_array << m7
92
+ elsif m8.present?
93
+ att_array << m8
94
+ end
95
+ end
96
+
97
+ if !att_hash.empty?
98
+ att_hash
99
+ elsif !att_array.empty?
100
+ att_array
101
+ else
102
+ text.lstrip
103
+ end
104
+ end
105
+
106
+ def strip_shortcodes(content)
107
+ if @shortcode_tags.any?
108
+ content.gsub(get_shortcode_regex){ strip_shortcode_tag *($~.to_a) }
109
+ else
110
+ content
111
+ end
112
+ end
113
+
114
+ def strip_shortcode_tag(*m)
115
+ # allow [[foo]] syntax for escaping a tag
116
+ if m[1] == '[' && m[6] == ']'
117
+ m[0][1..-2]
118
+ else
119
+ m[1] + m[6]
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'shortcodes/version'
5
+
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "ruby-shortcodes"
9
+ spec.version = Shortcodes::VERSION
10
+ spec.authors = ["David Lee"]
11
+ spec.email = ["david.lee@envato.com"]
12
+ spec.description = %q{implement stupid Wordpress shortcodes in ruby}
13
+ spec.summary = %q{implement stupid Wordpress shortcodes in ruby}
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency 'activesupport'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ end
File without changes
@@ -0,0 +1,227 @@
1
+ require 'spec_helper'
2
+ require 'shortcodes'
3
+
4
+ describe Shortcodes::TutsShortcodes do
5
+ subject(:shortcodes) { Shortcodes::TutsShortcodes.new }
6
+
7
+ describe '[xml]' do
8
+ it 'returns an appropriate pre tag for xml' do
9
+ xml_shortcode = '
10
+ [xml]
11
+ <div class="class">
12
+ Some Text
13
+ </div>
14
+ [/xml]
15
+ '
16
+ expected = '
17
+ <pre class="brush: xml">
18
+ <div class="class">
19
+ Some Text
20
+ </div></pre>
21
+ '
22
+ shortcodes.process(xml_shortcode).should == expected
23
+ end
24
+ end
25
+
26
+ describe '[sponsored_content]' do
27
+ it 'returns an appropriate div tag for sponsored content' do
28
+ shortcode = '
29
+ [sponsored_content]
30
+ <a href="http://www.filterforge.com/?psdtuts" onclick="javascript:_gaq.push([\'_trackEvent\',\'outbound-article\',\'www.filterforge.com\']);" sl-processed="1">Filter Forge</a>
31
+ [/sponsored_content]
32
+ '
33
+ expected = '<div class="sponsored-shortcode"><strong>Sponsored Content</strong><p>This content was commissioned by <a href="http://www.filterforge.com/?psdtuts" onclick="javascript:_gaq.push([\'_trackEvent\',\'outbound-article\',\'www.filterforge.com\']);" sl-processed="1">Filter Forge</a> and was written and/or edited by the Tuts+ team. Our aim with sponsored content is to publish relevant and objective tutorials, case studies, and inspirational interviews that offer genuine educational value to our readers and enable us to fund the creation of more useful content.</p></div>'
34
+
35
+ shortcodes.process(shortcode).strip.should == expected
36
+ end
37
+ end
38
+
39
+ describe '[sourcecode]' do
40
+ it 'returns an appropriate pre tag for the given language attribute of sourcecode' do
41
+ bash_shortcode = '
42
+ [sourcecode language="php"]
43
+ some php code
44
+ [/sourcecode]
45
+ '
46
+ expected = '
47
+ <pre class="brush: php">
48
+ some php code</pre>
49
+ '
50
+ shortcodes.process(bash_shortcode).should == expected
51
+ end
52
+
53
+ it 'returns an appropriate pre tag for the given lang attribute of sourcecode' do
54
+ bash_shortcode = '
55
+ [sourcecode lang="php"]
56
+ some php code
57
+ [/sourcecode]
58
+ '
59
+ expected = '
60
+ <pre class="brush: php">
61
+ some php code</pre>
62
+ '
63
+ shortcodes.process(bash_shortcode).should == expected
64
+ end
65
+
66
+ it 'uses plain brush as its default syntax if language attribute is not given' do
67
+ bash_shortcode = '
68
+ [sourcecode]
69
+ some random code
70
+ [/sourcecode]
71
+ '
72
+ expected = '
73
+ <pre class="brush: plain">
74
+ some random code</pre>
75
+ '
76
+ shortcodes.process(bash_shortcode).should == expected
77
+ end
78
+
79
+ it 'returns nothing for a content-less shortcode tag' do
80
+ shortcode = '[sourcecode language="php"]'
81
+ expected = ''
82
+ shortcodes.process(shortcode).should == expected
83
+ end
84
+ end
85
+
86
+ describe '[code]' do
87
+ it 'behaves the same as sourcecode' do
88
+ bash_shortcode = '
89
+ [code language="php"]
90
+ some php code
91
+ [/code]
92
+ '
93
+ expected = '
94
+ <pre class="brush: php">
95
+ some php code</pre>
96
+ '
97
+ shortcodes.process(bash_shortcode).should == expected
98
+ end
99
+ end
100
+
101
+ describe '[tip]' do
102
+ let(:source) { '[tip]In doing something for the first time, imagine that you have already
103
+ done it in the past.[/tip]' }
104
+ let(:expected) { '<div class="tip-shortcode">In doing something for the first time, imagine that you have already
105
+ done it in the past.</div>' }
106
+
107
+ it 'wraps the tip in a div (WTF)' do
108
+ shortcodes.process(source).should == expected
109
+ end
110
+
111
+ context 'when tip has no content' do
112
+ let(:source) { '[tip]' }
113
+
114
+ it 'returns nothing' do
115
+ shortcodes.process(source).should == ''
116
+ end
117
+ end
118
+ end
119
+
120
+ describe '[polldaddy]' do
121
+ let(:source) { '[polldaddy id="3382283" title="Whee whoo haha"]' }
122
+ let(:expected) { '<script type="text/javascript" charset="utf-8" src="http://static.polldaddy.com/p/3382283.js"></script>'}
123
+
124
+ it 'produces a polldaddy script tag' do
125
+ shortcodes.process(source).should == expected
126
+ end
127
+ end
128
+
129
+ describe '[audio]' do
130
+
131
+ context "when type not specified" do
132
+ let(:source) { '[audio http://hello.com]' }
133
+ let(:expected) { '<audio src="http://hello.com" />'}
134
+
135
+ it 'produces an audio tag' do
136
+ shortcodes.process(source).should == expected
137
+ end
138
+ end
139
+
140
+ context "when audio is separated from the tag with a colon with no space" do
141
+ let(:source) { '[audio:http://hello.com]' }
142
+ let(:expected) { '<audio src="http://hello.com" />'}
143
+
144
+ it 'produces an audio tag' do
145
+ shortcodes.process(source).should == expected
146
+ end
147
+ end
148
+
149
+ context "when audio is separated from the tag with a colon and whitespace" do
150
+ let(:source) { '[audio: http://hello.com]' }
151
+ let(:expected) { '<audio src="http://hello.com" />'}
152
+
153
+ it 'produces an audio tag' do
154
+ shortcodes.process(source).should == expected
155
+ end
156
+
157
+ context "and the URL contains whitespace" do
158
+ let(:source) { '[audio: http://how silly.com]' }
159
+ let(:expected) { '<audio src="http://how silly.com" />'}
160
+
161
+ it "retains the full path with the whitespace" do
162
+ shortcodes.process(source).should == expected
163
+ end
164
+ end
165
+ end
166
+
167
+ context "when type is specified as mp3" do
168
+ let(:source) { "[audio mp3='http://hello.com']" }
169
+ let(:expected) { %Q[<audio src="http://hello.com" type='audio/mpeg; codecs=\"mp3\"' />]}
170
+
171
+ it 'produces an audio tag w/ an mp3 codec' do
172
+ shortcodes.process(source).should == expected
173
+ end
174
+ end
175
+
176
+ context "when type is specified as ogg" do
177
+ let(:source) { "[audio ogg='http://hello.com']" }
178
+ let(:expected) { %Q[<audio src="http://hello.com" type='audio/ogg; codecs=\"vorbis\"' />]}
179
+
180
+ it 'produces an audio tag w/ an ogg codec' do
181
+ shortcodes.process(source).should == expected
182
+ end
183
+ end
184
+
185
+ end
186
+
187
+ describe '[WP_UnityObject]' do
188
+ let(:source) { '[WP_UnityObject src="http://activetuts.s3.amazonaws.com/tuts/448_unity4/preview/WebPlayer.unity3d" width="600" height="450" /]' }
189
+ let(:expected) { %{<script src="http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject2.js"></script><script async>$(function(){new UnityObject2().initPlugin($('.unity-player')[0], "http://activetuts.s3.amazonaws.com/tuts/448_unity4/preview/WebPlayer.unity3d");});</script><div class="unity-player" style="width:600px;height:450px"><div class="unity-player__missing"><a href="http://unity3d.com/webplayer/"><img alt="Unity Web Player. Install now!" src="http://webplayer.unity3d.com/installation/getunity.png" width="193" height="63" /></a></div></div>} }
190
+
191
+ it 'produces a unity object tag' do
192
+ shortcodes.process(source).should == expected
193
+ end
194
+ end
195
+
196
+ describe '[caption]' do
197
+ context 'with valid image and caption' do
198
+ let(:image) { '<img src="http://localhost/wp-content/uploads/2010/07/800px-Great_Wave_off_Kanagawa2-300x205.jpg" alt="Kanagawa" title="The Great Wave" width="300" height="205" class="size-medium wp-image-6" />' }
199
+ let(:caption) { 'WordPress shortcodes always exist for a good reason' }
200
+ let(:source) { %([caption id="attachment_6" align="alignright" width="300"]#{image} #{caption}[/caption]) }
201
+
202
+ it 'wraps content in figure and figcaption tags' do
203
+ expect(shortcodes.process(source)).to eq %(<figure class="post_image">#{image}<figcaption>#{caption}</figcaption></figure>)
204
+ end
205
+ end
206
+
207
+ context 'with invalid content' do
208
+ let(:content) { 'All content is valid content' }
209
+ let(:source) { %([caption id="attachment_5" align="alignright" width="300"]#{content}[/caption]) }
210
+
211
+ it 'returns content' do
212
+ expect(shortcodes.process(source)).to eq content
213
+ end
214
+ end
215
+ end
216
+
217
+ describe '[player]' do
218
+ let(:source) { '[player href="http://s3.amazonaws.com/nettuts/631_myows/apiRegister.flv" width="600" height="494"]' }
219
+ let(:expected) { %{<video class="post__content-video" src="http://s3.amazonaws.com/nettuts/631_myows/apiRegister.flv" width="600" height="494" />} }
220
+
221
+ # This relies on some html5 player being initialised for all <video> tags. In the case of Hub at the time of writing
222
+ # we already have mediaelement loaded for Courses videos, so this just works.
223
+ it 'produces a video tag' do
224
+ shortcodes.process(source).should == expected
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'shortcodes'
3
+
4
+ describe Shortcodes::WordpressShortcodes do
5
+ subject(:shortcodes) { Shortcodes::WordpressShortcodes.new }
6
+
7
+ describe '#process' do
8
+ it 'executes a simple shortcode' do
9
+ shortcodes.add_shortcode('foo'){ 'foo!' }
10
+ shortcodes.process('A [foo]').should == 'A foo!'
11
+ end
12
+
13
+ it 'executes a wrapping shortcode and passes contents' do
14
+ shortcodes.add_shortcode('foo'){ |attr, content| "foo#{content}!" }
15
+ shortcodes.process('A [foo]bar[/foo] Totally').should == 'A foobar! Totally'
16
+ end
17
+
18
+ it 'executes a shortcode with attributes' do
19
+ shortcodes.add_shortcode('foo'){ |attr| "foo to the #{attr['adjective']}, #{attr['noun']}!"}
20
+ shortcodes.process('[foo noun="fox" adjective="owlish"]').should == 'foo to the owlish, fox!'
21
+ end
22
+
23
+ it 'executes a shortcode with attributes and content' do
24
+ shortcodes.add_shortcode('foo'){ |attr, content| "#{content} to the #{attr['adjective']}, #{attr['noun']}!"}
25
+ shortcodes.process('[foo noun="fox" adjective="owlish"]Greetings[/foo]').should == 'Greetings to the owlish, fox!'
26
+ end
27
+
28
+ it 'executes multiple shortcodes in a string' do
29
+ shortcodes.add_shortcode('banana'){ "Bananas, yum!" }
30
+ shortcodes.add_shortcode('pizza'){ "Pizza, yum!" }
31
+ shortcodes.process('[banana] [pizza] [banana]').should == 'Bananas, yum! Pizza, yum! Bananas, yum!'
32
+ end
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-shortcodes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.18
5
+ platform: ruby
6
+ authors:
7
+ - David Lee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-07-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
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
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: implement stupid Wordpress shortcodes in ruby
70
+ email:
71
+ - david.lee@envato.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/shortcodes.rb
83
+ - lib/shortcodes/tuts_shortcodes.rb
84
+ - lib/shortcodes/version.rb
85
+ - lib/shortcodes/wordpress_shortcodes.rb
86
+ - ruby-shortcodes.gemspec
87
+ - spec/spec_helper.rb
88
+ - spec/tuts_shortcodes_spec.rb
89
+ - spec/wordpress_shortcodes_spec.rb
90
+ homepage: ''
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 3.0.3
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: implement stupid Wordpress shortcodes in ruby
113
+ test_files:
114
+ - spec/spec_helper.rb
115
+ - spec/tuts_shortcodes_spec.rb
116
+ - spec/wordpress_shortcodes_spec.rb