octo-captioned-image 1.0.0

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: e29c820c38696a033e556886c7be11e3970c24bf
4
+ data.tar.gz: ebe27f212dcbdaf79713e0c87245fafccbcfe9de
5
+ SHA512:
6
+ metadata.gz: ea78442d170e734541bf1dbadc0cc30a1a9d2e9ee10837cf4ad7a05cad6bb50e6da2da8d42aafa47a2be1a33264a4bd90644b98a4238a4066b605eb664ec8f6e
7
+ data.tar.gz: f51146762929e60edcfdd87d3623a104ad33e6cd19c755a7e0af003988e6f8e617dff384a68f198b611d3c35ad6111896f6e81d089186e4532dbceabba1a50e8
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ### 1.0.0 (2015-04-13)
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Andrew Esler
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,161 @@
1
+ # Octopress Captioned Image
2
+
3
+ An Octopress ink plugin for creating captioned images.
4
+
5
+ [![Build Status](https://travis-ci.org/ajesler/octo-captioned-image.svg?branch=master)](https://travis-ci.org/ajesler/octo-captioned-image)
6
+
7
+ ## Example
8
+
9
+ ![Example Usage](https://github.com/ajesler/octo-captioned-image/raw/master/captioned-image-example.png)
10
+
11
+ is produced by
12
+
13
+ ```
14
+ {% captioned_image /images/kitten.jpeg "a kitten!" float:"left" chrome %}
15
+ {% captioned_image /images/ijen-fire.jpg "Fire on Mt Ijen by Dennis Stauffer via Flickr" float:"left" position:"bottom" chrome %}
16
+ ```
17
+
18
+ ## Installation
19
+
20
+ If you're using bundler add this gem to your site's Gemfile in the `:jekyll_plugins` group:
21
+
22
+ group :jekyll_plugins do
23
+ gem 'octo-captioned-image'
24
+ end
25
+
26
+ Then install the gem with Bundler
27
+
28
+ $ bundle
29
+
30
+ To install manually without bundler:
31
+
32
+ $ gem install octo-captioned-image
33
+
34
+ Then add the gem to your Jekyll configuration.
35
+
36
+ gems:
37
+ - octo-captioned-image
38
+
39
+ If you're using a standard Jekyll theme, add `{% css_asset_tag %}` to your site layout.
40
+
41
+
42
+ ## Syntax
43
+
44
+ ```
45
+ {% captioned_image src caption [width height] [position:top|bottom] [float:left|right] [clear:left|right|both] %}
46
+ ```
47
+
48
+ ### Properties
49
+
50
+ `src` and `caption` are required, the rest of the properties are optional.
51
+ Please note that both width and height must be given or neither given. `auto` can be used as a width and height value.
52
+
53
+ * `src`
54
+ this is required and can be an absolute or relative path.
55
+ * `caption`
56
+ this is required and must be surrounded by `"` or `'`. Any usages of the surrounding quote type (`"` or `'`) in the caption must be escaped like `\"` or `\'`. If you surrounded the caption with `"` then `'` in the caption do not need to be escaped, and vice versa.
57
+ * `width`
58
+ no default value
59
+ * `height`
60
+ no default value
61
+ * `float`
62
+ no default value
63
+ * `clear`
64
+ no default value
65
+ * `position`
66
+ defaults to `top`
67
+ * `chrome`
68
+ has no value, but if present will add a gradient background to the caption.
69
+
70
+
71
+ ## Examples
72
+
73
+ ```
74
+ {% captioned_image {{site.url}}/images/puppies.png "Look at the puppies!" %}
75
+
76
+ {% captioned_image {{site.url}}/images/adventure_awaits.gif "Adventure awaits!" float:"left" clear:"right" %}
77
+
78
+ {% captioned_image {{site.url}}/images/sad_robot.png "This is why we dont let machines have feelings" 1000px 500px position:bottom float:"left" clear:"right" chrome %}
79
+
80
+ {% captioned_image {{site.url}}/images/unimportant.jpg "And I said \"O'Leary is a fun guy!\"" clear:"both" position:"bottom" %}
81
+
82
+ // you can also embed html into the caption
83
+ // note that you will be need to careful with the html quotes.
84
+ {% captioned_image {{site.url}}/images/circuit-schematic.png "Circuit schematic - created with <a href='https://fritzing.org'>fritzing</a>" %}
85
+
86
+ // multiple images in a figure
87
+ // note that all the images will have the same caption, and that any size given will be applied to all images
88
+ {% captioned_image {{site.url}}/images/a-mouse.png {{site.url}}/images/a-bear.png "How to spot the difference between bears and mice" position:"bottom" chrome %}
89
+ ```
90
+
91
+ results in the following html
92
+
93
+ ```html
94
+ <figure class="captioned-image">
95
+ <figcaption class="caption-top">
96
+ Look at the puppies!
97
+ </figcaption>
98
+ <img src="http://yoursite.com/images/puppies.png" alt="Look at the puppies!">
99
+ </figure>
100
+
101
+ <figure class="captioned-image float-left clear-right">
102
+ <figcaption class="caption-top">
103
+ Adventure awaits!
104
+ </figcaption>
105
+ <img src="http://yoursite.com/images/adventure_awaits.gif" alt="Adventure awaits!">
106
+ </figure>
107
+
108
+ <figure class="captioned-image-chrome float-left clear-right">
109
+ <img src="http://yoursite.com/images/sad_robot.png" alt="This is why we dont let machines have feelings" width="1000px" height="500px">
110
+ <figcaption class="caption-bottom-chrome">
111
+ This is why we dont let machines have feelings
112
+ </figcaption>
113
+ </figure>
114
+
115
+ <figure class="captioned-image clear-both">
116
+ <img src="http://yoursite.com/images/unimportant.jpg" alt="And I said &quot;O'Leary is a fun guy!&quot;" width="1000px" height="500px">
117
+ <figcaption class="caption-bottom">
118
+ And I said &quot;O'Leary is a fun guy!&quot;
119
+ </figcaption>
120
+ </figure>
121
+
122
+ <figure class="captioned-image">
123
+ <figcaption class="caption-top">
124
+ Circuit schematic - created with <a href='http://fritzing.org'>fritzing</a>
125
+ </figcaption>
126
+ <img src="http://yoursite.com/images/circuit-schematic.png" alt="Circuit schematic - created with <a href='http://fritzing.org'>fritzing</a>" />
127
+ </figure>
128
+
129
+ <figure class="captioned-image-chrome">
130
+ <img src="http://yoursite.com/images/a-mouse.png" alt="How to spot the difference between bears and mice" />
131
+ <img src="http://yoursite.com/images/a-bear.png" alt="How to spot the difference between bears and mice" />
132
+ <figcaption class="caption-bottom-chrome">
133
+ How to spot the difference between bears and mice
134
+ </figcaption>
135
+ </figure>
136
+ ```
137
+
138
+ ## Customisation
139
+
140
+ To customise the styling, copy the stylesheet into your _plugins directory with the following command. You can then edit it and override the default styles.
141
+
142
+ ```
143
+ octopress ink copy octo-captioned-image --stylesheets
144
+ ```
145
+
146
+ ## Testing
147
+
148
+ There are two sets of tests; caption extraction/option parsing logic, and a rendered output check.
149
+
150
+ ```
151
+ rake test
152
+ bundle exec clash test
153
+ ```
154
+
155
+ ## Contributing
156
+
157
+ 1. Fork it ( https://github.com/ajesler/octo-captioned-image/fork )
158
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
159
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
160
+ 4. Push to the branch (`git push origin my-new-feature`)
161
+ 5. Create a new Pull Request
@@ -0,0 +1,74 @@
1
+ figure.captioned-image {
2
+ padding: 0;
3
+ margin: 1em 1em;
4
+ border: 0;
5
+ display: table;
6
+ font-size: 0.8em;
7
+ }
8
+
9
+ figure.captioned-image-chrome {
10
+ @extend figure.captioned-image;
11
+ border: 1px solid #cbcbcb;
12
+ }
13
+
14
+ figure.captioned-image img {
15
+ margin: 0;
16
+ padding: 0;
17
+ }
18
+
19
+ figcaption.captioned-image-caption {
20
+ margin: 0;
21
+ padding: 0;
22
+ position: relative;
23
+ text-align: center;
24
+ line-height: 2em;
25
+ display: table-caption;
26
+ }
27
+
28
+ figcaption.caption-top {
29
+ @extend figcaption.captioned-image-caption;
30
+ caption-side: top;
31
+ }
32
+
33
+ figcaption.caption-top-chrome {
34
+ @extend figcaption.caption-top;
35
+ text-shadow: rgba(255,255,255,0.8) 0 1px 0;
36
+ color: #474747;
37
+ background-color: #ccc;
38
+ background-image: linear-gradient(#fff, #f0f0f0 6%, #e5e5e5 90%, #e5e5e5);
39
+ border: 1px solid #cbcbcb;
40
+ border-top-left-radius: 5px;
41
+ border-top-right-radius: 5px;
42
+ }
43
+
44
+ figcaption.caption-bottom {
45
+ @extend figcaption.captioned-image-caption;
46
+ caption-side: bottom;
47
+ }
48
+
49
+ figcaption.caption-bottom-chome {
50
+ @extend figcaption.caption-bottom;
51
+ margin: -5px 0 0 0;
52
+ caption-side: bottom;
53
+ border-top-left-radius: 0px;
54
+ border-top-right-radius: 0px;
55
+ border-bottom-left-radius: 5px;
56
+ border-bottom-right-radius: 5px;
57
+ background-image: linear-gradient(#f0f0f0, #e5e5e5 90%, #e5e5e5);
58
+ }
59
+
60
+ figure.clear-both {
61
+ clear: both;
62
+ }
63
+ figure.clear-left {
64
+ clear: left;
65
+ }
66
+ figure.clear-right {
67
+ clear: right;
68
+ }
69
+ figure.float-left {
70
+ float: left;
71
+ }
72
+ figure.float-right {
73
+ float: right;
74
+ }
@@ -0,0 +1,85 @@
1
+ require "octo-captioned-image/version"
2
+ require "octo-captioned-image/caption_extractor"
3
+ require "octo-captioned-image/caption_options_parser"
4
+ require "octopress-ink"
5
+
6
+ module Octopress
7
+ module Tags
8
+ module CaptionedImageTag
9
+ class Tag < Liquid::Tag
10
+ # most of this class is copied from
11
+ # https://github.com/octopress/video-tag/blob/master/lib/octopress-video-tag.rb
12
+
13
+ def initialize(tag_name, markup, tokens)
14
+ @markup = markup
15
+ super
16
+ end
17
+
18
+ def render(context)
19
+ @markup = process_liquid(context) # what is this doing? should not replace markup
20
+
21
+ caption, remaining_markup = extract_caption(@markup)
22
+ options = parse_options(remaining_markup)
23
+
24
+ figure_classes = ["captioned-image#{'-chrome' if options.chrome}"]
25
+ figure_classes << "float-#{options.float}" if options.float
26
+ figure_classes << "clear-#{options.clear}" if options.clear
27
+ figure_class_decl = " class=\"#{figure_classes.join(' ')}\""
28
+
29
+ img_attributes = ""
30
+ img_attributes += "width=\"#{options.width}\" " if options.width
31
+ img_attributes += "height=\"#{options.height}\" " if options.height
32
+
33
+ figcaption_class = "caption-#{options.position}"
34
+ figcaption_class += "-chrome" if options.chrome
35
+
36
+ fig_caption = [" <figcaption class=\"#{figcaption_class}\">"]
37
+ fig_caption << " #{caption}"
38
+ fig_caption << " </figcaption>"
39
+
40
+ image = options.source.map do |src|
41
+ # should this caption be escaped if it contains html or quotes?
42
+ [" <img src=\"#{src}\" alt=\"#{caption}\" #{img_attributes}/>"]
43
+ end
44
+
45
+ figure_content = options.position == "top" ? fig_caption + image : image + fig_caption
46
+
47
+ figure = ["<figure#{figure_class_decl}>"]
48
+ figure += figure_content
49
+ figure << "</figure>"
50
+
51
+ return figure.join("\n")
52
+ end
53
+
54
+ def extract_caption(markup)
55
+ # the markup other methods use to find params has the caption removed to avoid parsing issues
56
+ caption, remaining_markup = CaptionExtractor.extract(markup)
57
+ return caption, remaining_markup
58
+ end
59
+
60
+ def parse_options(option_string)
61
+ CaptionOptionsParser.new(option_string)
62
+ end
63
+
64
+ def process_liquid(context)
65
+ Liquid::Template.parse(@markup).render!(context.environments.first)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ Liquid::Template.register_tag('captioned_image', Octopress::Tags::CaptionedImageTag::Tag)
73
+
74
+ Octopress::Ink.add_plugin({
75
+ name: "Octopress Captioned Image",
76
+ gem: "octo-captioned-image",
77
+ path: File.expand_path(File.join(File.dirname(__FILE__), "../")),
78
+ type: "plugin",
79
+
80
+ # Metadata which is displayed with plugin info
81
+ version: Octopress::Tags::CaptionedImageTag::VERSION,
82
+ description: "Create captioned images",
83
+ source_url: "https://github.com/ajesler/octo-captioned-image",
84
+ website: "https://github.com/ajesler/octo-captioned-image"
85
+ })
@@ -0,0 +1,60 @@
1
+ module Octopress
2
+ module Tags
3
+ module CaptionedImageTag
4
+ class CaptionExtractor
5
+
6
+ QSINGLE = "'"
7
+ QDOUBLE = '"'
8
+
9
+ def self.extract(markup)
10
+
11
+ # find the first quote instance
12
+ c, start = caption_start(markup)
13
+
14
+ partial = markup[start+1..-1]
15
+ fin = -1
16
+ caption = nil
17
+
18
+ partial.chars.each_with_index do |v,i|
19
+ if v == c && partial[i-1] != '\\'
20
+ fin = i
21
+ caption = partial[0..fin-1]
22
+ break
23
+ end
24
+ end
25
+
26
+ # remove the comment string from @mutable_markup
27
+ remainder = markup[0..(start-1)]+markup[(start+fin+2)..-1]
28
+
29
+ # swap " -> &quot; and ' -> &#39; in caption
30
+ if c == QDOUBLE
31
+ caption.gsub!("\\#{QDOUBLE}", "&quot;")
32
+ else
33
+ caption.gsub!("\\#{QSINGLE}", "&#39;")
34
+ end
35
+
36
+ return caption, remainder
37
+ end
38
+
39
+ private
40
+
41
+ def self.caption_start(markup)
42
+ di = markup.index(QDOUBLE)
43
+ si = markup.index(QSINGLE)
44
+
45
+ if di && si && di < si
46
+ return QDOUBLE, di
47
+ elsif di && si && si < di
48
+ return QSINGLE, si
49
+ elsif di && !si
50
+ return QDOUBLE, di
51
+ elsif si && !di
52
+ return QSINGLE, si
53
+ else
54
+ raise "Could not find a quoted caption in #{@markup}"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,59 @@
1
+ module Octopress
2
+ module Tags
3
+ module CaptionedImageTag
4
+ class CaptionOptionsParser
5
+
6
+ attr_reader :position, :width, :height, :source, :float, :clear, :chrome
7
+ DEFAULT_POSITION = "top"
8
+
9
+ Source = /((https?:\/\/|\/)\S+\.(png|gif|bmp|jpe?g)\S*)/i
10
+ Dimensions = /\s(auto|\d\S+)/i
11
+ Position = /(:?position:\s*"?(:?\w+))/i
12
+ Float = /(:?float:\s*"?(:?\w+))/i
13
+ Clear = /(:?clear:\s*"?(:?\w+))/i
14
+ Chrome = /chrome/
15
+
16
+ def initialize(markup)
17
+ @markup = markup
18
+
19
+ parse_source
20
+ raise "No source image (png, gif, bmp, or jpeg) found in #{@markup}" unless @source
21
+
22
+ parse_position
23
+ parse_float
24
+ parse_clear
25
+ parse_dimensions
26
+ parse_chrome
27
+ end
28
+
29
+ private
30
+
31
+ def parse_source
32
+ @source = @markup.scan(Source).map(&:first).compact
33
+ end
34
+
35
+ def parse_position
36
+ @position = @markup.scan(Position).flatten.last || DEFAULT_POSITION
37
+ end
38
+
39
+ def parse_float
40
+ @float = @markup.scan(Float).flatten.last
41
+ end
42
+
43
+ def parse_clear
44
+ @clear = @markup.scan(Clear).flatten.last
45
+ end
46
+
47
+ def parse_dimensions
48
+ dimensions = @markup.scan(Dimensions).map(&:first).compact
49
+ @width = dimensions[0]
50
+ @height = dimensions[1]
51
+ end
52
+
53
+ def parse_chrome
54
+ @chrome = @markup =~ Chrome
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ module Octopress
2
+ module Tags
3
+ module CaptionedImageTag
4
+ VERSION = "1.0.0"
5
+ end
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: octo-captioned-image
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Esler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: octopress-ink
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.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.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: clash
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ description: " octo-captioned-image adds captioned images to octopress v3. It uses
84
+ the figure and figcaption tags. Styling can be customised. \n"
85
+ email:
86
+ - aj@esler.co.nz
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - CHANGELOG.md
92
+ - LICENSE.txt
93
+ - README.md
94
+ - assets/stylesheets/main.scss
95
+ - lib/octo-captioned-image.rb
96
+ - lib/octo-captioned-image/caption_extractor.rb
97
+ - lib/octo-captioned-image/caption_options_parser.rb
98
+ - lib/octo-captioned-image/version.rb
99
+ homepage: https://github.com/ajesler/octo-captioned-image
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.4.5
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Creates captioned images for octopress v3
123
+ test_files: []