markdown_datafier 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +64 -0
- data/Rakefile +1 -0
- data/lib/markdown_datafier/version.rb +3 -0
- data/lib/markdown_datafier.rb +136 -0
- data/markdown_datafier.gemspec +25 -0
- data/spec/fixtures/config/config.yml +1 -0
- data/spec/fixtures/content/index.mdown +10 -0
- data/spec/fixtures/content/section-one/index.mdown +9 -0
- data/spec/fixtures/content/section-one/sub-one-test-one.mdown +10 -0
- data/spec/fixtures/content/section-two/child-section-one/child-one-test-one.mdown +11 -0
- data/spec/fixtures/content/section-two/child-section-one/index.mdown +10 -0
- data/spec/fixtures/content/section-two/index.mdown +10 -0
- data/spec/fixtures/content/section-two/sub-two-test-one.mdown +10 -0
- data/spec/fixtures/content/splash.mdown +10 -0
- data/spec/fixtures/content/test-one.mdown +12 -0
- data/spec/fixtures/content/test-two.mdown +10 -0
- data/spec/markdown_datafier_spec.rb +228 -0
- data/spec/spec_helper.rb +17 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 607b54af89db3284975d223c6d65e16969fd5543
|
4
|
+
data.tar.gz: 9b6d04683df30a585501b9b1275721b4489a3b75
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7da5a7ffd2d82ca0b6b18dd3c0b2eb57d901ecb511becb45ed892a1b087f4fcb7b5ae56aeaab2e80c679f3277b3cc57294a681c657eed4fa25754b6d4a19a99b
|
7
|
+
data.tar.gz: ce610fdd99247490a027bc52f132bb7ca9a47d0871777df2366dbf9be18706d23d3dac3d1b5bb94f82d494cfd0ec740a26e0deeb2cfe2d8e0803084af65e8b1e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 J. Ryan Williams
|
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,64 @@
|
|
1
|
+
# MarkdownDatafier
|
2
|
+
|
3
|
+
MarkdownDatafier is a ruby gem which reads a structure of Markdown files, parses their metadata and outputs to a simple hash. It is framework agnostic, configurable to any content and configuration location and easy to plug into your own API endpoints or controller actions.
|
4
|
+
|
5
|
+
This is currently in an early alpha stage. Though it is likely to remain simple, there will undoubtedly be some feature additions and improvement to things like exception handling. This gem was developed using Ruby 2.0.0p247.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'markdown_datafier'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install markdown_datafier
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Create an object for your server and include MarkdownDatafier:
|
24
|
+
|
25
|
+
class MyServerObject
|
26
|
+
include MarkdownDatafier
|
27
|
+
end
|
28
|
+
|
29
|
+
Then create an instance of the server using the full path to your config directory:
|
30
|
+
|
31
|
+
server = MyServerObject.new(config_directory: "/path/to/config/")
|
32
|
+
|
33
|
+
Inside your configuration directory, configure your config.yml file like so:
|
34
|
+
|
35
|
+
content_directory: '/absolute/path/to/content/directory/'
|
36
|
+
|
37
|
+
Files are accessed individually by their "shortname" (the file name path inside your content_directory minus the extension, OR the parent directory name)
|
38
|
+
|
39
|
+
content = server.find_by_path(some-existing-file)
|
40
|
+
|
41
|
+
You can also get the home page like so:
|
42
|
+
|
43
|
+
content = server.home_page
|
44
|
+
|
45
|
+
Or a splash page like so:
|
46
|
+
|
47
|
+
content = server.splash_page
|
48
|
+
|
49
|
+
You can also grab a collection of indexes for the top level sections of your content
|
50
|
+
|
51
|
+
collection = server.indexes_for_sections
|
52
|
+
|
53
|
+
Or specify a sub level (for instance by using the "shortname" of previously retrieved section):
|
54
|
+
|
55
|
+
collection = server.indexes_for_sections("/section-two")
|
56
|
+
|
57
|
+
|
58
|
+
## Contributing
|
59
|
+
|
60
|
+
1. Fork it
|
61
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
63
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
64
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require "markdown_datafier/version"
|
2
|
+
require "time"
|
3
|
+
require "redcarpet"
|
4
|
+
|
5
|
+
module MarkdownDatafier
|
6
|
+
attr_accessor :config
|
7
|
+
class MetadataParseError < RuntimeError; end
|
8
|
+
|
9
|
+
def self.root
|
10
|
+
File.expand_path '../..', __FILE__
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(attributes)
|
14
|
+
set_config_directory(attributes[:config_directory])
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_config_directory(path)
|
18
|
+
@config = YAML.load_file( path + "config.yml")
|
19
|
+
end
|
20
|
+
|
21
|
+
def content_directory
|
22
|
+
@config["content_directory"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def home_page
|
26
|
+
find_by_path("index")
|
27
|
+
end
|
28
|
+
|
29
|
+
def splash_page
|
30
|
+
find_by_path("splash")
|
31
|
+
end
|
32
|
+
|
33
|
+
def indexes_for_sections(directory=nil)
|
34
|
+
sections = []
|
35
|
+
if directory.nil?
|
36
|
+
Dir.chdir(content_directory)
|
37
|
+
currrent_dir_name = ""
|
38
|
+
else
|
39
|
+
Dir.chdir(content_directory + directory)
|
40
|
+
currrent_dir_name = File.basename(Dir.pwd)
|
41
|
+
end
|
42
|
+
sub_directories.each do |section|
|
43
|
+
sections << find_by_path(currrent_dir_name + section)
|
44
|
+
end
|
45
|
+
sections
|
46
|
+
end
|
47
|
+
|
48
|
+
def sub_directories
|
49
|
+
sub_directories = Dir["*"].reject{|file| not File.directory?(file)}.map! {|sub_directory| "/" + sub_directory }
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_by_path(shortname)
|
53
|
+
path = determine_file_path(content_directory + strip_leading_slashes(shortname))
|
54
|
+
content = "Shortname: #{shortname}\nCreate Datetime: #{File.ctime(path)}\n" + File.open(path).read
|
55
|
+
parse_file_content(content)
|
56
|
+
end
|
57
|
+
|
58
|
+
def strip_leading_slashes(shortname)
|
59
|
+
shortname.match(/^\//) ? shortname.gsub(/^\//, "") : shortname
|
60
|
+
end
|
61
|
+
|
62
|
+
def determine_file_path(path)
|
63
|
+
is_directory?(path) ? serve_index(path) : append_file_extention(path)
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_directory?(path)
|
67
|
+
File.directory?(path)
|
68
|
+
end
|
69
|
+
|
70
|
+
def serve_index(shortname)
|
71
|
+
shortname.match(/\/$/) ? (shortname + "index.mdown") : (shortname + "/index.mdown")
|
72
|
+
end
|
73
|
+
|
74
|
+
def append_file_extention(path)
|
75
|
+
path + ".mdown"
|
76
|
+
end
|
77
|
+
|
78
|
+
def underscores_to_dashes(shortname)
|
79
|
+
shortname.gsub(/_/, "-")
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_file_content(content)
|
83
|
+
convert_body_to_html(set_meta_defaults(determine_publish_datetime(parse_meta(split_meta_and_body(content)))))
|
84
|
+
end
|
85
|
+
|
86
|
+
def split_meta_and_body(content)
|
87
|
+
meta, body = content.split(/\r?\n\r?\n/, 2)
|
88
|
+
{:meta => meta}.merge!({:body => body})
|
89
|
+
end
|
90
|
+
|
91
|
+
def parse_meta(content_hash)
|
92
|
+
is_metadata = content_hash[:meta].split("\n").first =~ /^[\w ]+:/
|
93
|
+
raise MetadataParseError unless is_metadata
|
94
|
+
parsed_hash = Hash.new
|
95
|
+
content_hash[:meta].split("\n").each do |line|
|
96
|
+
key, value = line.split(/\s*:\s*/, 2)
|
97
|
+
next if value.nil?
|
98
|
+
parsed_hash[key.downcase.gsub(/\s+/, "_").to_sym] = value.chomp
|
99
|
+
end
|
100
|
+
content_hash[:meta] = parsed_hash
|
101
|
+
content_hash
|
102
|
+
end
|
103
|
+
|
104
|
+
def determine_publish_datetime(content_hash)
|
105
|
+
if [:date, :publish_date, :publish_datetime].any? {|symbol| content_hash[:meta].key? symbol}
|
106
|
+
content_hash[:meta][:publish_datetime] = Time.parse(content_hash[:meta][:publish_datetime]).utc.iso8601 if content_hash[:meta][:publish_datetime]
|
107
|
+
content_hash[:meta][:publish_datetime] = Time.parse(content_hash[:meta].delete(:date)).utc.iso8601 if content_hash[:meta][:date]
|
108
|
+
content_hash[:meta][:publish_datetime] = Time.parse(content_hash[:meta].delete(:publish_date)).utc.iso8601 if content_hash[:meta][:publish_date]
|
109
|
+
else
|
110
|
+
content_hash[:meta][:publish_datetime] = Time.parse(content_hash[:meta][:create_datetime]).utc.iso8601
|
111
|
+
end
|
112
|
+
content_hash
|
113
|
+
end
|
114
|
+
|
115
|
+
def set_meta_defaults(content_hash)
|
116
|
+
meta_hash = content_hash[:meta]
|
117
|
+
meta_hash[:nav_name] ||= default_nav_name(content_hash[:body])
|
118
|
+
meta_hash[:position] ||= nil
|
119
|
+
meta_hash[:large_image] ||= nil
|
120
|
+
meta_hash[:medium_image] ||= nil
|
121
|
+
meta_hash[:small_image] ||= nil
|
122
|
+
content_hash[:meta] = meta_hash
|
123
|
+
content_hash
|
124
|
+
end
|
125
|
+
|
126
|
+
def default_nav_name(body)
|
127
|
+
body.split(/\r?\n\r?\n/, 2)[0].gsub(/# /, "")
|
128
|
+
end
|
129
|
+
|
130
|
+
def convert_body_to_html(content_hash)
|
131
|
+
converter = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true)
|
132
|
+
content_hash[:body] = converter.render(content_hash[:body])
|
133
|
+
content_hash
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'markdown_datafier/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "markdown_datafier"
|
8
|
+
spec.version = MarkdownDatafier::VERSION
|
9
|
+
spec.authors = ["J. Ryan Williams"]
|
10
|
+
spec.email = ["ryan@websuasion.com"]
|
11
|
+
spec.description = %q{API data structure generated from Markdown files}
|
12
|
+
spec.summary = %q{Reads a structure of Markdown files parses their metadata and outputs to a ruby hash or array of hashes. Easy to plug into your own API endpoints.}
|
13
|
+
spec.homepage = "https://github.com/etherdev/markdown_datafier"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "redcarpet"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec", "~> 2.11"
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
content_directory: '/path/to/your/content/'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Title Tag: My Homepage | My Website
|
2
|
+
Description: This is a description meta for the home page.
|
3
|
+
Keywords: rspec, testing, markdown
|
4
|
+
Publish Date: 23 July 2010 00:00 EST
|
5
|
+
Summary: This is a summary text for the home page.
|
6
|
+
Nav Name: Home
|
7
|
+
|
8
|
+
# Homepage
|
9
|
+
|
10
|
+
This is the home page.
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Title Tag: Subsection 1 Index | My Website
|
2
|
+
Description: This is a description meta for the subsection 1 index.
|
3
|
+
Keywords: rspec, testing, markdown
|
4
|
+
Publish Date: 23 July 2010 00:00 EST
|
5
|
+
Summary: This is a summary text for the subsection 1 index.
|
6
|
+
|
7
|
+
# Subsection 1 Index
|
8
|
+
|
9
|
+
This is the subsection one index.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Title Tag: My Subsection 1 Test Page 1 | My Website
|
2
|
+
Description: This is a description meta for subsection 1 test page 1.
|
3
|
+
Keywords: rspec, testing, markdown
|
4
|
+
Publish Date: 23 July 2010 00:00 EST
|
5
|
+
Summary: This is a summary text for subsection 1 test page 1.
|
6
|
+
Nav Name: One Deep
|
7
|
+
|
8
|
+
# Test Page 1
|
9
|
+
|
10
|
+
This is the first subsection test page.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Status: published
|
2
|
+
Title Tag: Subsection Child 1 Test 1 | My Website
|
3
|
+
Description: This is a description meta for the subsection child 1 test 1.
|
4
|
+
Keywords: rspec, testing, markdown
|
5
|
+
Publish Date: 23 July 2010 00:00 EST
|
6
|
+
Summary: This is a summary text for the subsection child 1 test 1.
|
7
|
+
Nav Name: Two Deep
|
8
|
+
|
9
|
+
# Subsection Child 1 Test 1
|
10
|
+
|
11
|
+
This is the subsection child one test 1.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Status: published
|
2
|
+
Title Tag: Subsection Child 1 Index | My Website
|
3
|
+
Description: This is a description meta for the subsection child 1 index.
|
4
|
+
Keywords: rspec, testing, markdown
|
5
|
+
Publish Date: 23 July 2010 00:00 EST
|
6
|
+
Summary: This is a summary text for the subsection child 1 index.
|
7
|
+
|
8
|
+
# Subsection Child 1 Index
|
9
|
+
|
10
|
+
This is the subsection child one index.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Status: published
|
2
|
+
Title Tag: Subsection 2 Index | My Website
|
3
|
+
Description: This is a description meta for the subsection 2 index.
|
4
|
+
Keywords: rspec, testing, markdown
|
5
|
+
Publish Date: 23 July 2010 00:00 EST
|
6
|
+
Summary: This is a summary text for the subsection 2 index.
|
7
|
+
|
8
|
+
# Subsection 2 Index
|
9
|
+
|
10
|
+
This is the subsection two index.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Status: draft
|
2
|
+
Title Tag: My Subsection 2 Test Page 1 | My Website
|
3
|
+
Description: This is a description meta for subsection 2 test page 1.
|
4
|
+
Keywords: rspec, testing, markdown
|
5
|
+
Publish Date: 23 July 2010 00:00 EST
|
6
|
+
Summary: This is a summary text for subsection 2 test page 1.
|
7
|
+
|
8
|
+
# Subsection 2 Test Page 1
|
9
|
+
|
10
|
+
This is the second subsection test page 1.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Title Tag: My Home Splash | My Website
|
2
|
+
Description: This is a description meta for the home spalsh.
|
3
|
+
Keywords: rspec, testing, markdown
|
4
|
+
Publish Date: 23 July 2010 00:00 EST
|
5
|
+
Summary: This is a summary text for home splash.
|
6
|
+
Large Image: http://mysite.com/images/home_splash.png
|
7
|
+
|
8
|
+
# Home Splash
|
9
|
+
|
10
|
+
This is the home splash.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Title Tag: My Test Page 1 | My Website
|
2
|
+
Description: This is a description meta for test page 1.
|
3
|
+
Keywords: rspec, testing, markdown
|
4
|
+
Publish Date: 23 July 2010 00:00 EST
|
5
|
+
Summary: This is a summary text for test page 1.
|
6
|
+
Large Image: http://mysite.com/images/test-one-500x500.png
|
7
|
+
Medium Image: http://mysite.com/images/test-one-200x200.png
|
8
|
+
Small Image: http://mysite.com/images/test-one-75x75.png
|
9
|
+
|
10
|
+
# Test Page 1
|
11
|
+
|
12
|
+
This is the first test page.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Title Tag: My Test Page 2 | My Website
|
2
|
+
Description: This is a description meta for test page 2.
|
3
|
+
Keywords: rspec, testing, markdown
|
4
|
+
Publish Date: 23 July 2010 00:00 EST
|
5
|
+
Summary: This is a summary text for test page 2.
|
6
|
+
Position: 2
|
7
|
+
|
8
|
+
# Test Page 2
|
9
|
+
|
10
|
+
This is the second test page.
|
@@ -0,0 +1,228 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe MarkdownDatafier do
|
4
|
+
|
5
|
+
let(:server) { TestServer.new( config_directory: MarkdownDatafier.root + "/spec/fixtures/config/" )}
|
6
|
+
|
7
|
+
describe "initialization" do
|
8
|
+
|
9
|
+
it "should load configuration settings" do
|
10
|
+
expect(server.content_directory).to eq "/path/to/your/content/"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "file parsing" do
|
15
|
+
let(:contents) { File.open(server.content_directory + "test-one.mdown").read }
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
server.config["content_directory"] = MarkdownDatafier.root + "/spec/fixtures/content/"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should strip leading slashes from shortname" do
|
22
|
+
shortname = "/test-one"
|
23
|
+
expect(server.strip_leading_slashes(shortname)).to eq "test-one"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should change underscores to dashes" do
|
27
|
+
shortname = "test_one_two_three"
|
28
|
+
expect(server.underscores_to_dashes(shortname)).to eq "test-one-two-three"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should check if requested path is a directory" do
|
32
|
+
path = MarkdownDatafier.root + "/spec/fixtures/content/section-two/child-section-one"
|
33
|
+
expect(server.is_directory?(path)).to eq true
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should split the meta and body" do
|
37
|
+
expect(server.split_meta_and_body(contents)).to include(:meta, :body)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should set publish_datetime when it is provided" do
|
41
|
+
provided_content = {:meta=>
|
42
|
+
{:create_datetime=>"2013-10-21 23:12:06 -0400",
|
43
|
+
:publish_datetime=>"23 July 2010 00:00 EST"}}
|
44
|
+
result = server.determine_publish_datetime(provided_content)
|
45
|
+
expect(result[:meta][:publish_datetime]).to eq "2010-07-23T05:00:00Z"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should set publish_datetime from provided publish date" do
|
49
|
+
provided_content = {:meta=>
|
50
|
+
{:create_datetime=>"2013-10-21 23:12:06 -0400",
|
51
|
+
:publish_date=>"23 July 2010"}}
|
52
|
+
result = server.determine_publish_datetime(provided_content)
|
53
|
+
expect(result[:meta][:publish_datetime]).to eq "2010-07-23T04:00:00Z"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should set publish_datetime from provided date" do
|
57
|
+
provided_content = {:meta=>
|
58
|
+
{:create_datetime=>"2013-10-21 23:12:06 -0400",
|
59
|
+
:date=>"23 July 2010 00:00 EST"}}
|
60
|
+
result = server.determine_publish_datetime(provided_content)
|
61
|
+
expect(result[:meta][:publish_datetime]).to eq "2010-07-23T05:00:00Z"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should set publish_datetime from create datetime when no date meta is provided" do
|
65
|
+
provided_content = {:meta=>
|
66
|
+
{:create_datetime=>"2013-10-21 23:12:06 -0400"}}
|
67
|
+
result = server.determine_publish_datetime(provided_content)
|
68
|
+
expect(result[:meta][:publish_datetime]).to eq "2013-10-22T03:12:06Z"
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "resolve shortname to absolute path" do
|
72
|
+
|
73
|
+
it "with leading slash directory index request" do
|
74
|
+
expect(server.find_by_path("/section-two")[:meta][:title_tag]).to eq "Subsection 2 Index | My Website"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "with trailing slash directory index request" do
|
78
|
+
expect(server.find_by_path("section-two/")[:meta][:title_tag]).to eq "Subsection 2 Index | My Website"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "with leading and trailing slash directory index request" do
|
82
|
+
expect(server.find_by_path("/section-two/")[:meta][:title_tag]).to eq "Subsection 2 Index | My Website"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "with middle only slash on a non-index subdirectory file" do
|
86
|
+
expect(server.find_by_path("section-one/sub-one-test-one")[:meta][:title_tag]).to eq "My Subsection 1 Test Page 1 | My Website"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "with middle only slash on a child subdirectory request" do
|
90
|
+
expect(server.find_by_path("section-two/child-section-one")[:meta][:title_tag]).to eq "Subsection Child 1 Index | My Website"
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "with existing content" do
|
97
|
+
|
98
|
+
before(:each) do
|
99
|
+
server.config["content_directory"] = MarkdownDatafier.root + "/spec/fixtures/content/"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should return the home page content" do
|
103
|
+
expect(server.home_page[:meta][:title_tag]).to eq "My Homepage | My Website"
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should hide indexes as root directories" do
|
107
|
+
expect(server.home_page[:meta][:title_tag]).to eq "My Homepage | My Website"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should return the splash page" do
|
111
|
+
expect(server.splash_page[:meta][:title_tag]).to eq "My Home Splash | My Website"
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should return a populated array of indexes for top level sections" do
|
115
|
+
expect(server.indexes_for_sections()).to have(2).items
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return a populated array of indexes for the specified section's child directories" do
|
119
|
+
expect(server.indexes_for_sections("/section-two")).to have(1).items
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return an empty array for section with no child directories" do
|
123
|
+
expect(server.indexes_for_sections("section-one/")).to be_empty
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should return the appropriate first index for sections in the array" do
|
127
|
+
expect(server.indexes_for_sections.first[:meta][:title_tag]).to eq "Subsection 1 Index | My Website"
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should deliver index file for a root directory request" do
|
131
|
+
expect(server.find_by_path("/")[:meta][:shortname]).to eq "/"
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should return a file from a section directory" do
|
135
|
+
expect(server.find_by_path("section-one/sub-one-test-one")[:meta][:nav_name]).to eq "One Deep"
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should return a file from a child of section directory" do
|
139
|
+
expect(server.find_by_path("section-two/child-section-one/child-one-test-one")[:meta][:nav_name]).to eq "Two Deep"
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "should deliver an index file from a subdirectory directory request" do
|
143
|
+
it "with no trailing slash" do
|
144
|
+
expect(server.find_by_path("/section-two")[:meta][:nav_name]).to eq "Subsection 2 Index"
|
145
|
+
end
|
146
|
+
|
147
|
+
it "with trailing slash" do
|
148
|
+
expect(server.find_by_path("/section-two/")[:meta][:nav_name]).to eq "Subsection 2 Index"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "should deliver an index file from a child directory directory request" do
|
153
|
+
it "with no trailing slash" do
|
154
|
+
expect(server.find_by_path("/section-two/child-section-one")[:meta][:nav_name]).to eq "Subsection Child 1 Index"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "with trailing slash" do
|
158
|
+
expect(server.find_by_path("/section-two/child-section-one/")[:meta][:nav_name]).to eq "Subsection Child 1 Index"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "should return the correct" do
|
163
|
+
it "shortname" do
|
164
|
+
expect(server.find_by_path("test-one")[:meta][:shortname]).to eq "test-one"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "title_tag" do
|
168
|
+
expect(server.find_by_path("test-one")[:meta][:title_tag]).to eq "My Test Page 1 | My Website"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "description" do
|
172
|
+
expect(server.find_by_path("test-one")[:meta][:description]).to eq "This is a description meta for test page 1."
|
173
|
+
end
|
174
|
+
|
175
|
+
it "keywords" do
|
176
|
+
expect(server.find_by_path("test-one")[:meta][:keywords]).to eq "rspec, testing, markdown"
|
177
|
+
end
|
178
|
+
|
179
|
+
it "publish_date in UTC ISO 8601 format" do
|
180
|
+
expect(server.find_by_path("test-one")[:meta][:publish_datetime]).to eq "2010-07-23T05:00:00Z"
|
181
|
+
end
|
182
|
+
|
183
|
+
it "nav_name when supplied" do
|
184
|
+
expect(server.find_by_path("/")[:meta][:nav_name]).to eq "Home"
|
185
|
+
end
|
186
|
+
|
187
|
+
it "nav_name when not supplied" do
|
188
|
+
expect(server.find_by_path("test-one")[:meta][:nav_name]).to eq "Test Page 1"
|
189
|
+
end
|
190
|
+
|
191
|
+
it "summary" do
|
192
|
+
expect(server.find_by_path("test-one")[:meta][:summary]).to eq "This is a summary text for test page 1."
|
193
|
+
end
|
194
|
+
|
195
|
+
it "large_image" do
|
196
|
+
expect(server.find_by_path("test-one")[:meta][:large_image]).to eq "http://mysite.com/images/test-one-500x500.png"
|
197
|
+
end
|
198
|
+
|
199
|
+
it "medium_image" do
|
200
|
+
expect(server.find_by_path("test-one")[:meta][:medium_image]).to eq "http://mysite.com/images/test-one-200x200.png"
|
201
|
+
end
|
202
|
+
|
203
|
+
it "small_image" do
|
204
|
+
expect(server.find_by_path("test-one")[:meta][:small_image]).to eq "http://mysite.com/images/test-one-75x75.png"
|
205
|
+
end
|
206
|
+
|
207
|
+
it "position of nil" do
|
208
|
+
expect(server.find_by_path("test-one")[:meta][:position]).to be_nil
|
209
|
+
end
|
210
|
+
|
211
|
+
it "position of 2" do
|
212
|
+
expect(server.find_by_path("test-two")[:meta][:position]).to eq "2"
|
213
|
+
end
|
214
|
+
|
215
|
+
it "body in html format" do
|
216
|
+
expect(server.find_by_path("test-one")[:body]).to include("<h1>Test Page 1</h1>")
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
describe ".root" do
|
224
|
+
it "should return the gem's root directory" do
|
225
|
+
expect(File.basename(MarkdownDatafier.root)).to eq "markdown_datafier"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../lib/markdown_datafier'
|
2
|
+
|
3
|
+
class TestServer
|
4
|
+
include MarkdownDatafier
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
config.order = 'random'
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: markdown_datafier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- J. Ryan Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redcarpet
|
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: '2.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.11'
|
69
|
+
description: API data structure generated from Markdown files
|
70
|
+
email:
|
71
|
+
- ryan@websuasion.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/markdown_datafier.rb
|
83
|
+
- lib/markdown_datafier/version.rb
|
84
|
+
- markdown_datafier.gemspec
|
85
|
+
- spec/fixtures/config/config.yml
|
86
|
+
- spec/fixtures/content/index.mdown
|
87
|
+
- spec/fixtures/content/section-one/index.mdown
|
88
|
+
- spec/fixtures/content/section-one/sub-one-test-one.mdown
|
89
|
+
- spec/fixtures/content/section-two/child-section-one/child-one-test-one.mdown
|
90
|
+
- spec/fixtures/content/section-two/child-section-one/index.mdown
|
91
|
+
- spec/fixtures/content/section-two/index.mdown
|
92
|
+
- spec/fixtures/content/section-two/sub-two-test-one.mdown
|
93
|
+
- spec/fixtures/content/splash.mdown
|
94
|
+
- spec/fixtures/content/test-one.mdown
|
95
|
+
- spec/fixtures/content/test-two.mdown
|
96
|
+
- spec/markdown_datafier_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
homepage: https://github.com/etherdev/markdown_datafier
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.0.5
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Reads a structure of Markdown files parses their metadata and outputs to
|
122
|
+
a ruby hash or array of hashes. Easy to plug into your own API endpoints.
|
123
|
+
test_files:
|
124
|
+
- spec/fixtures/config/config.yml
|
125
|
+
- spec/fixtures/content/index.mdown
|
126
|
+
- spec/fixtures/content/section-one/index.mdown
|
127
|
+
- spec/fixtures/content/section-one/sub-one-test-one.mdown
|
128
|
+
- spec/fixtures/content/section-two/child-section-one/child-one-test-one.mdown
|
129
|
+
- spec/fixtures/content/section-two/child-section-one/index.mdown
|
130
|
+
- spec/fixtures/content/section-two/index.mdown
|
131
|
+
- spec/fixtures/content/section-two/sub-two-test-one.mdown
|
132
|
+
- spec/fixtures/content/splash.mdown
|
133
|
+
- spec/fixtures/content/test-one.mdown
|
134
|
+
- spec/fixtures/content/test-two.mdown
|
135
|
+
- spec/markdown_datafier_spec.rb
|
136
|
+
- spec/spec_helper.rb
|