Skip to content

Commit f22b09a

Browse files
committed
Initial commit
0 parents  commit f22b09a

12 files changed

+237
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/Gemfile.lock

.rspec

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--format documentation
2+
--color
3+
--require spec_helper

Gemfile

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
source "https://rubygems.org"
2+
3+
gemspec

LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2018 Tom Dalling
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.

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Jekyll::IncludeSnippet
2+
3+
Include snippets of text from external files into your markdown
4+
5+
## Installation
6+
7+
TODO: here
8+
9+
## Usage
10+
11+
TODO: Write usage instructions here
12+
13+
## License
14+
15+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).

jekyll-include-snippet.gemspec

+27
Original file line numberDiff line numberDiff line change
@@ -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 "jekyll/include_snippet/version"
5+
6+
Gem::Specification.new do |spec|
7+
spec.name = "jekyll-include_snippet"
8+
spec.version = Jekyll::IncludeSnippet::VERSION
9+
spec.authors = ["Tom Dalling"]
10+
spec.email = ["[email protected]"]
11+
12+
spec.summary = %q{Include snippets of text from external files into your markdown}
13+
spec.homepage = "https://github.com/tomdalling/jekyll-include_snippet"
14+
spec.license = "MIT"
15+
16+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
17+
f.match(%r{^(test|spec|features)/})
18+
end
19+
spec.bindir = "exe"
20+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21+
spec.require_paths = ["lib"]
22+
23+
spec.add_development_dependency "bundler", "~> 1.15"
24+
spec.add_development_dependency "rspec", "~> 3.7"
25+
spec.add_development_dependency "rspec-its", "~> 1.2"
26+
spec.add_development_dependency "byebug"
27+
end

lib/jekyll/include_snippet.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Jekyll
2+
module IncludeSnippet
3+
end
4+
end
5+
6+
%w(version extractor).each do |file|
7+
require "jekyll/include_snippet/#{file}"
8+
end
9+
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
module Jekyll
2+
module IncludeSnippet
3+
class Extractor
4+
BEGIN_REGEX = %r{
5+
(\s*)\#\s* # Line must start with a hash (surrounding whitespace optional)
6+
begin-snippet: # Magic string for beginning a snippet
7+
(.+) # The remainder of the line is the snippet name
8+
}x
9+
10+
END_REGEX = %r{
11+
\s*\#\s* # Line must start with a hash (surrounding whitespace optional)
12+
end-snippet # Magic string for ending a snippet
13+
}x
14+
15+
def call(source)
16+
everything = Snippet.new(name: 'everything', indent: 0)
17+
all_snippets = []
18+
active_snippets = []
19+
20+
source.each_line do |line|
21+
case line
22+
when BEGIN_REGEX
23+
active_snippets << Snippet.new(name: $2.strip, indent: $1.length)
24+
when END_REGEX
25+
all_snippets << active_snippets.pop
26+
else
27+
(active_snippets + [everything]).each do |snippet|
28+
snippet.lines << line
29+
end
30+
end
31+
end
32+
33+
(all_snippets + [everything])
34+
.map { |s| [s.name, s.dedented_text] }
35+
.to_h
36+
end
37+
38+
private
39+
40+
def hash_from_snippets(snippets)
41+
end
42+
43+
class Snippet
44+
attr_reader :name, :indent, :lines
45+
46+
def initialize(name:, indent:)
47+
@name = name
48+
@indent = indent
49+
@lines = []
50+
end
51+
52+
def dedented_text
53+
lines
54+
.map { |l| l[indent..-1] }
55+
.join
56+
.rstrip
57+
end
58+
end
59+
end
60+
end
61+
end

lib/jekyll/include_snippet/version.rb

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Jekyll
2+
module IncludeSnippet
3+
VERSION = "0.1.0"
4+
end
5+
end

spec/extractor_spec.rb

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
RSpec.describe Jekyll::IncludeSnippet::Extractor do
2+
subject { extractor.(input) }
3+
let(:extractor) { described_class.new }
4+
5+
context 'a simple snippet' do
6+
let(:input) { <<~END_INPUT }
7+
This is the first line
8+
9+
# begin-snippet: wakka
10+
This is the wakka snippet.
11+
# end-snippet
12+
13+
Last line.
14+
END_INPUT
15+
16+
its(['wakka']) { is_expected.to eq('This is the wakka snippet.') }
17+
its(['everything']) { is_expected.to eq(<<~END_TEXT.strip) }
18+
This is the first line
19+
20+
This is the wakka snippet.
21+
22+
Last line.
23+
END_TEXT
24+
end
25+
26+
context 'nested snippets' do
27+
let(:input) { <<~END_INPUT }
28+
#begin-snippet: outer
29+
This is outer
30+
#begin-snippet: inner
31+
This is inner
32+
#end-snippet
33+
#end-snippet
34+
END_INPUT
35+
36+
its(['inner']) { is_expected.to eq('This is inner') }
37+
its(['outer']) { is_expected.to eq("This is outer\nThis is inner") }
38+
end
39+
40+
context 'indented snippets' do
41+
let(:input) { <<~END_INPUT }
42+
First
43+
#begin-snippet: indented
44+
I
45+
am
46+
indented
47+
#end-snippet
48+
Last
49+
END_INPUT
50+
51+
its(['indented']) { is_expected.to eq(
52+
[
53+
" I",
54+
" am",
55+
" indented"
56+
].join("\n")
57+
) }
58+
59+
its(['everything']) { is_expected.to eq(
60+
[
61+
"First",
62+
" I",
63+
" am",
64+
" indented",
65+
"Last"
66+
].join("\n")
67+
) }
68+
end
69+
end

spec/jekyll-include_snippet_spec.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require "spec_helper"
2+
3+
RSpec.describe Jekyll::IncludeSnippet do
4+
it "has a version number" do
5+
expect(Jekyll::IncludeSnippet::VERSION.split('.').size).to eq(3)
6+
end
7+
end

spec/spec_helper.rb

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
require "bundler/setup"
2+
require 'rspec/its'
3+
require 'byebug'
4+
require "jekyll/include_snippet"
5+
6+
RSpec.configure do |config|
7+
# Enable flags like --only-failures and --next-failure
8+
config.example_status_persistence_file_path = ".rspec_status"
9+
10+
# Disable RSpec exposing methods globally on `Module` and `main`
11+
config.disable_monkey_patching!
12+
13+
config.expect_with :rspec do |c|
14+
c.syntax = :expect
15+
end
16+
end

0 commit comments

Comments
 (0)