md_splitter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Guardfile +9 -0
- data/README +45 -0
- data/Rakefile +1 -0
- data/bin/md_splitter +55 -0
- data/lib/.DS_Store +0 -0
- data/lib/md_splitter/.DS_Store +0 -0
- data/lib/md_splitter/elf_manifest_builder.rb +60 -0
- data/lib/md_splitter/splitter.rb +146 -0
- data/lib/md_splitter/version.rb +3 -0
- data/lib/md_splitter.rb +5 -0
- data/md_splitter.gemspec +35 -0
- data/samples/sample.md +21 -0
- data/spec/bin/md_splitter_spec.rb +1 -0
- data/spec/ilb/md_splitter/manifest_builder_spec.rb +129 -0
- data/spec/ilb/md_splitter/splitter_spec.rb +218 -0
- metadata +184 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create 1.9.2@md_splitter
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# MD_Splitter #
|
2
|
+
|
3
|
+
Accepts a markdown file as input and uses Kramdown to convert to HTML. Optionally splits the source document using a given string and saves multiple output docs.
|
4
|
+
|
5
|
+
## Install ##
|
6
|
+
|
7
|
+
% gem install md_splitter
|
8
|
+
|
9
|
+
SYNOPSIS:
|
10
|
+
|
11
|
+
md_splitter split [options] files
|
12
|
+
|
13
|
+
OR
|
14
|
+
|
15
|
+
md_splitter [options] files
|
16
|
+
|
17
|
+
OPTIONS:
|
18
|
+
|
19
|
+
-s, --split_on STRING
|
20
|
+
Splits the source doc into multiple html files on the provided string
|
21
|
+
|
22
|
+
-o, --output_path STRING
|
23
|
+
Defines custom output path for saving resulting files
|
24
|
+
|
25
|
+
-d, --dry_run STRING
|
26
|
+
Non-destructive test pass
|
27
|
+
|
28
|
+
EXAMPLES:
|
29
|
+
|
30
|
+
* Convert a markdown file to htm
|
31
|
+
|
32
|
+
md_splitter path/to/file.md
|
33
|
+
|
34
|
+
* Split a markdown file into multiple htm
|
35
|
+
|
36
|
+
md_splitter --split_on '---' path/to/file.md
|
37
|
+
|
38
|
+
* Specify an output directory for the converted files
|
39
|
+
|
40
|
+
md_splitter --output_path 'target/file/path' path/to/file.md
|
41
|
+
|
42
|
+
* Use dry run to preview results without changing any files
|
43
|
+
|
44
|
+
md_splitter --dry_run path/to/file.md
|
45
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/md_splitter
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'commander/import'
|
5
|
+
require './lib/md_splitter'
|
6
|
+
require './lib/md_splitter/splitter.rb'
|
7
|
+
|
8
|
+
program :version, '0.1'
|
9
|
+
program :description, 'Splits markdown docs into multiple html files'
|
10
|
+
|
11
|
+
global_option('-v', '--verbose', "Tell me stuff")
|
12
|
+
|
13
|
+
command :split do |c|
|
14
|
+
md_splitter = MdSplitter::Splitter.new
|
15
|
+
c.syntax = 'md_splitter split [options]'
|
16
|
+
c.description = 'Accepts markdown documents as input and saves them as html. Optionally splits source into multiple output docs'
|
17
|
+
c.example 'Convert a markdown file to htm', 'md_splitter path/to/file.md'
|
18
|
+
c.example 'Split a markdown file into multiple htm', "md_splitter --split_on '---' path/to/file.md"
|
19
|
+
c.example 'Specify an output directory for the converted files', "md_splitter --output_path 'target/file/path' path/to/file.md"
|
20
|
+
c.example 'Use dry run to preview results without changing any files', "md_splitter --dry_run path/to/file.md"
|
21
|
+
c.example 'Set :manifest to true to write a json manifest', "md_splitter --manifest true path/to/file.md"
|
22
|
+
c.option '-s', '--split_on STRING', String, "Splits the source doc into multiple html files on the provided string"
|
23
|
+
c.option '-o', '--output_path STRING', String, "Defines custom output path for saving resulting files"
|
24
|
+
c.option '-d', '--dry_run STRING', String, "Non-destructive test pass"
|
25
|
+
c.option '-m', '--manifest STRING', String, "Create a manifest file"
|
26
|
+
c.action do |args, options|
|
27
|
+
# Do something or c.when_called Md_splitter::Commands::Split
|
28
|
+
if options.dry_run
|
29
|
+
say "Invoking dry run split"
|
30
|
+
else
|
31
|
+
say "Invoking live split"
|
32
|
+
end
|
33
|
+
opts = {
|
34
|
+
:dry_run => options.dry_run.nil? ? false : true,
|
35
|
+
:output_path => options.output_path,
|
36
|
+
:split_on => options.split_on,
|
37
|
+
:manifest => options.manifest.nil? ? false : true
|
38
|
+
}
|
39
|
+
|
40
|
+
puts opts
|
41
|
+
|
42
|
+
args.each do |arg|
|
43
|
+
md_splitter.split arg, opts
|
44
|
+
# if options.split_on
|
45
|
+
# say "Splitting #{arg} on #{options.split_on}"
|
46
|
+
# md_splitter.split arg, :split_on => options.split_on
|
47
|
+
# else
|
48
|
+
# say "Converting #{arg} to html"
|
49
|
+
# md_splitter.split arg
|
50
|
+
# end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
default_command :split
|
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'uuidtools'
|
3
|
+
|
4
|
+
module MdSplitter
|
5
|
+
class ElfManifestBuilder
|
6
|
+
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# * *Args* :
|
10
|
+
# - ++ ->
|
11
|
+
# * *Returns* :
|
12
|
+
# -
|
13
|
+
# * *Raises* :
|
14
|
+
# - ++ ->
|
15
|
+
#
|
16
|
+
def initialize items
|
17
|
+
@items = build_manifest_object items
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
# Accepts an ennumerable object and returns a json manifest
|
22
|
+
#
|
23
|
+
# * *Args* :
|
24
|
+
# - items -> OBJECT from which to build the manifest
|
25
|
+
# * *Returns* :
|
26
|
+
# - JSON manifest
|
27
|
+
# * *Raises* :
|
28
|
+
# - ++ ->
|
29
|
+
#
|
30
|
+
def raw
|
31
|
+
@items
|
32
|
+
end
|
33
|
+
|
34
|
+
def json
|
35
|
+
JSON.pretty_generate raw
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_manifest_object items
|
42
|
+
pages = Array.new
|
43
|
+
items.each do |item|
|
44
|
+
pages << get_page_object(item)
|
45
|
+
end
|
46
|
+
{
|
47
|
+
:id => UUIDTools::UUID.random_create.to_s,
|
48
|
+
:pages => pages
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_page_object item
|
53
|
+
{
|
54
|
+
:id => File.basename(item, File.extname(item)),
|
55
|
+
:name => File.basename(item, File.extname(item)),
|
56
|
+
:url => File.basename(item)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'Kramdown'
|
2
|
+
require 'fileutils'
|
3
|
+
require './lib/md_splitter/elf_manifest_builder'
|
4
|
+
|
5
|
+
module MdSplitter
|
6
|
+
# Your code goes here...
|
7
|
+
|
8
|
+
=begin rdoc
|
9
|
+
Wraps Kramdown for converting Markdown documents to html, with a few extra features
|
10
|
+
=end
|
11
|
+
class Splitter
|
12
|
+
KRAM_OPTIONS = { :input => "kramdown", :output => "html" }
|
13
|
+
LIVE_PREFIX = "Live ->"
|
14
|
+
DRY_RUN_PREFIX = "Dry Run ->"
|
15
|
+
DEFAULTS = {
|
16
|
+
:dry_run => false,
|
17
|
+
:split_on => nil,
|
18
|
+
:output_path => nil,
|
19
|
+
:manifest => nil
|
20
|
+
}
|
21
|
+
|
22
|
+
def initialize opts = {}
|
23
|
+
@mode = "LIVE"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Accepts a path to a markdown document and converts it to html
|
27
|
+
# optionally splits it to multiple output files
|
28
|
+
# * *Args* :
|
29
|
+
# - path -> String, path to source markdown doc
|
30
|
+
# - options -> Hash of following options
|
31
|
+
# - :split_on -> STRING marker to split the document on
|
32
|
+
# - :dry_run -> BOOL performs no file actions if TRUE
|
33
|
+
# - :output_path -> STRING where to save resulting files
|
34
|
+
def split path, options = {}
|
35
|
+
@options = DEFAULTS.merge options
|
36
|
+
pages = Array.new
|
37
|
+
|
38
|
+
src_markdown = read_file_contents path
|
39
|
+
target_path = get_target_path(path)
|
40
|
+
create_output_path target_path
|
41
|
+
source_file_name = get_source_file_name(path)
|
42
|
+
say "No files will be hurt in this operation" if @options[:dry_run]
|
43
|
+
|
44
|
+
if options[:split_on].nil?
|
45
|
+
htm = convert_md_to_html(src_markdown)
|
46
|
+
output_file_name = get_target_file_name(source_file_name)
|
47
|
+
pages << "#{output_file_name}.html"
|
48
|
+
save_file File.join("#{target_path}","#{output_file_name}.html"), htm
|
49
|
+
say "Converting #{source_file_name} to html"
|
50
|
+
else
|
51
|
+
say "Splitting #{source_file_name} on '#{options[:split_on]}'"
|
52
|
+
mds = src_markdown.split(options[:split_on])
|
53
|
+
output_path = target_path
|
54
|
+
output_file_name = get_target_file_name(source_file_name)
|
55
|
+
|
56
|
+
if @options[:output_path].nil?
|
57
|
+
# if no output path specified, and more than one output file required
|
58
|
+
# then create a child directory to store the multiple files
|
59
|
+
target_path = File.join "#{target_path}", "#{output_file_name}" if mds.length > 1
|
60
|
+
create_output_path target_path
|
61
|
+
end
|
62
|
+
|
63
|
+
mds.each do |md|
|
64
|
+
htm = convert_md_to_html(md)
|
65
|
+
file_suffix = ""
|
66
|
+
if mds.length > 1
|
67
|
+
|
68
|
+
file_suffix = "_#{mds.index(md) + 1}"
|
69
|
+
end
|
70
|
+
|
71
|
+
pages << "#{output_file_name}#{file_suffix}.html"
|
72
|
+
save_file File.join("#{target_path}","#{output_file_name}#{file_suffix}.html"), htm
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# save a manifest if requested
|
77
|
+
save_manifest(pages, target_path) if @options[:manifest]
|
78
|
+
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def save_manifest pages, directory
|
85
|
+
say "Writing manifest"
|
86
|
+
manifest = MdSplitter::ElfManifestBuilder.new pages
|
87
|
+
save_file File.join(directory, "manifest.json"), manifest.json
|
88
|
+
end
|
89
|
+
|
90
|
+
def convert_md_to_html md
|
91
|
+
Kramdown::Document.new(md.strip, KRAM_OPTIONS).to_html
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_target_path path
|
95
|
+
target = File.dirname path
|
96
|
+
# check for custom export path
|
97
|
+
unless @options[:output_path].nil?
|
98
|
+
target = File.join(target, @options[:output_path])
|
99
|
+
end
|
100
|
+
target
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_source_file_name path
|
104
|
+
File.basename(path) # returns just the file name and extension
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_target_file_name src_path
|
108
|
+
File.basename(src_path, File.extname(src_path))
|
109
|
+
end
|
110
|
+
|
111
|
+
def create_output_path target_path
|
112
|
+
FileUtils.mkpath "#{target_path}"
|
113
|
+
end
|
114
|
+
|
115
|
+
def read_file_contents path
|
116
|
+
# return sample if only a dry run
|
117
|
+
return "# Sample Header" if @options[:dry_run]
|
118
|
+
target_file = File.open path, 'rb'
|
119
|
+
target_file.read
|
120
|
+
end
|
121
|
+
|
122
|
+
def save_file path, content
|
123
|
+
say "Writing #{path}"
|
124
|
+
unless @options[:dry_run]
|
125
|
+
File.open(path, 'w') do |f|
|
126
|
+
f.write content
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Puts messages to the console
|
132
|
+
#
|
133
|
+
# * *Args* :
|
134
|
+
# - message -> STRING - message to display
|
135
|
+
def say message
|
136
|
+
case @options[:dry_run]
|
137
|
+
when true
|
138
|
+
prefix = DRY_RUN_PREFIX
|
139
|
+
else
|
140
|
+
prefix = LIVE_PREFIX
|
141
|
+
end
|
142
|
+
puts "#{prefix} #{message}"
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
data/lib/md_splitter.rb
ADDED
data/md_splitter.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "md_splitter/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "md_splitter"
|
7
|
+
s.version = MdSplitter::VERSION
|
8
|
+
s.authors = ["Darren Wallace"]
|
9
|
+
s.email = ["wallace@midweekcrisis.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Prepares Markdown docs for web delivery}
|
12
|
+
s.description = %q{Parses md docs for split markers and produces multiple html files and a json manifest}
|
13
|
+
|
14
|
+
s.rubyforge_project = "md_splitter"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "rake", "~> 0.9.2"
|
24
|
+
s.add_development_dependency "bundler", "~> 1.0.21"
|
25
|
+
s.add_development_dependency "rspec", "~> 2.7.0"
|
26
|
+
s.add_development_dependency "guard-rspec"
|
27
|
+
s.add_development_dependency "growl"
|
28
|
+
s.add_development_dependency "rb-fsevent"
|
29
|
+
|
30
|
+
|
31
|
+
s.add_runtime_dependency "kramdown", "~> 0.13.3"
|
32
|
+
s.add_runtime_dependency "commander", "~> 4.0.6"
|
33
|
+
s.add_runtime_dependency "json", "~> 1.6.1"
|
34
|
+
s.add_runtime_dependency "uuidtools", "~> 2.1.2"
|
35
|
+
end
|
data/samples/sample.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Header 1 #
|
2
|
+
|
3
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
4
|
+
|
5
|
+
---
|
6
|
+
|
7
|
+
* Hello
|
8
|
+
* this
|
9
|
+
* is
|
10
|
+
|
11
|
+
---
|
12
|
+
|
13
|
+
|
14
|
+
* a
|
15
|
+
* list
|
16
|
+
|
17
|
+
---
|
18
|
+
|
19
|
+
## Header 2 ##
|
20
|
+
|
21
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
@@ -0,0 +1 @@
|
|
1
|
+
describe "md_splitter command line"
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'md_splitter/elf_manifest_builder'
|
2
|
+
|
3
|
+
describe "Build an ELF manifest." do
|
4
|
+
before(:each) do
|
5
|
+
@subject = MdSplitter::ElfManifestBuilder.new get_test_object
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should respond to a raw method" do
|
9
|
+
@subject.should respond_to(:raw)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "Return manifest object." do
|
13
|
+
before(:each) do
|
14
|
+
@result = @subject.raw
|
15
|
+
end
|
16
|
+
|
17
|
+
it "result should be a hash object" do
|
18
|
+
@result.should be_a(Hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have an id property" do
|
22
|
+
@result[:id].should be_a String
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a pages array" do
|
26
|
+
@result[:pages].should be_an Array
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "Pages array." do
|
30
|
+
it "should contain page objects" do
|
31
|
+
@result[:pages].each do |page|
|
32
|
+
page.should be_a Hash
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "Page objects" do
|
37
|
+
it "should have an id" do
|
38
|
+
@result[:pages].each do |page|
|
39
|
+
page[:id].should be_a String
|
40
|
+
end
|
41
|
+
end
|
42
|
+
it "should have a name" do
|
43
|
+
@result[:pages].each do |page|
|
44
|
+
page[:name].should be_a String
|
45
|
+
end
|
46
|
+
end
|
47
|
+
it "should have a url" do
|
48
|
+
@result[:pages].each do |page|
|
49
|
+
page[:url].should be_a String
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "id's and names should match source item names" do
|
54
|
+
get_test_object.each_index do |i|
|
55
|
+
@result[:pages][i][:id].should eq get_test_object_names[i]
|
56
|
+
@result[:pages][i][:name].should eq get_test_object_names[i]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "url should match the source item" do
|
61
|
+
get_test_object.each_index do |i|
|
62
|
+
@result[:pages][i][:url].should eq get_test_object[i]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "Return json manifest" do
|
70
|
+
it "json manifest should be a string" do
|
71
|
+
@subject.json.should be_a String
|
72
|
+
puts @subject.json
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be parsable as a json object" do
|
76
|
+
obj = JSON.parse(@subject.json)
|
77
|
+
obj.should be_a Hash
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
|
86
|
+
# Builds test object from which to test manifest
|
87
|
+
def get_test_object
|
88
|
+
test_obj = ["page1.html", "page2.html", "page3.html"]
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_test_object_names
|
92
|
+
return ['page1', 'page2', 'page3']
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_test_result
|
96
|
+
"[\"page1.html\",\"page2.html\",\"page3.html\"]"
|
97
|
+
end
|
98
|
+
|
99
|
+
def sample_elf_template
|
100
|
+
{
|
101
|
+
:id => "#{item}"
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
def sample_elf_manifest
|
106
|
+
<<-eos
|
107
|
+
{
|
108
|
+
"id":"859d7b55-61fa-42fd-8b34-ae0f9c664bd71",
|
109
|
+
"pages":
|
110
|
+
[
|
111
|
+
{
|
112
|
+
"id":"page1",
|
113
|
+
"name":"Page 1",
|
114
|
+
"url":"page1.html"
|
115
|
+
},
|
116
|
+
{
|
117
|
+
"id":"page2",
|
118
|
+
"name":"Page 2",
|
119
|
+
"url":"page2.html"
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"id":"page3",
|
123
|
+
"name":"Page 3",
|
124
|
+
"url":"page3.html"
|
125
|
+
}
|
126
|
+
]
|
127
|
+
}
|
128
|
+
eos
|
129
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'md_splitter/splitter'
|
2
|
+
require 'md_splitter/elf_manifest_builder'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
describe "Splitter" do
|
6
|
+
before(:each) do
|
7
|
+
@subject = MdSplitter::Splitter.new
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "split" do
|
11
|
+
it "should have a split method" do
|
12
|
+
@subject.should respond_to :split
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "converts an unsplit markdown file" do
|
16
|
+
it "should save html to single file" do
|
17
|
+
mock_input_file_read "sample.md"
|
18
|
+
# expect call to Kramdown
|
19
|
+
mock_kramdown(sample_markdown.strip).should_receive(:to_html).and_return(simple_html)
|
20
|
+
mock_output_file_write "./sample.html"
|
21
|
+
|
22
|
+
# Should tell the user what we're doing
|
23
|
+
STDOUT.should_receive(:puts).with("Live -> Writing ./sample.html")
|
24
|
+
STDOUT.should_receive(:puts).with("Live -> Converting sample.md to html")
|
25
|
+
|
26
|
+
@subject.split "sample.md"
|
27
|
+
# TODO: find way to confirm data properly written to file
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should deal with folder hierarchies" do
|
31
|
+
mock_input_file_read "fake/path/sample.md"
|
32
|
+
# expect call to Kramdown
|
33
|
+
mock_kramdown(sample_markdown.strip).should_receive(:to_html).and_return(simple_html)
|
34
|
+
mock_output_file_write "fake/path/sample.html"
|
35
|
+
@subject.split "fake/path/sample.md"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "splits a markdown page into multiple files" do
|
40
|
+
it "should accept optional parameters" do
|
41
|
+
@subject.should respond_to(:split).with(1).arguments # accepts just the target file
|
42
|
+
@subject.should respond_to(:split).with(2).argument # accepts an optional extra parameter
|
43
|
+
end
|
44
|
+
it "should use the split_on option to split the src into multiple files" do
|
45
|
+
mock_doc_split
|
46
|
+
@subject.split "fake/path/sample.md", :split_on => "---\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should create the folder structure when necessary" do
|
50
|
+
mock_doc_split
|
51
|
+
# when splitting a file, should create the target path if necessary
|
52
|
+
FileUtils.should_receive(:mkpath).with('fake/path/sample')
|
53
|
+
@subject.split "fake/path/sample.md", :split_on => "---\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
# it "should 'say' what we're doing" do
|
57
|
+
# mock_doc_split
|
58
|
+
# STDOUT.should_receive(:puts).with(/Splitting sample.md/).once
|
59
|
+
# @subject.split "fake/path/sample.md", :split_on => "---\n"
|
60
|
+
# end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "support a custom output path" do
|
64
|
+
it "for single files" do
|
65
|
+
mock_input_file_read "fake/path/sample.md"
|
66
|
+
mock_output_file_write "fake/path/exports/sample.html"
|
67
|
+
@subject.split "fake/path/sample.md", :output_path => "exports"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should use the custom path for split files" do
|
71
|
+
mock_input_file_read "fake/path/sample.md"
|
72
|
+
mock_output_file_write "fake/path/exports/sample.html", 3
|
73
|
+
FileUtils.should_receive(:mkpath).with('fake/path/exports')
|
74
|
+
@subject.split "fake/path/sample.md", :output_path => "exports", :split_on => "---"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "dry run" do
|
79
|
+
before(:each) do
|
80
|
+
@subject = MdSplitter::Splitter.new
|
81
|
+
end
|
82
|
+
it "should not perform any file actions" do
|
83
|
+
make_safe_file_stubs
|
84
|
+
File.should_not_receive(:open)
|
85
|
+
@subject.split "fake/path/sample.md", :split_on => "---\n", :dry_run => true
|
86
|
+
end
|
87
|
+
it "should say when we're in dry_run mode" do
|
88
|
+
make_safe_file_stubs
|
89
|
+
STDOUT.should_receive(:puts).with(/^Dry Run/i).at_least(:once)
|
90
|
+
@subject.split "fake/path/sample.md", :split_on => "---\n", :dry_run => true
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "create a manifest if requested" do
|
95
|
+
before(:each) do
|
96
|
+
mock_input_file_read "fake/path/sample.md"
|
97
|
+
mock_output_file_write "fake/path/sample/sample.html", 3
|
98
|
+
mock_output_file_write "fake/path/sample/manifest.json"
|
99
|
+
@duff_builder = double()
|
100
|
+
@duff_builder.stub(:json)
|
101
|
+
@subject = MdSplitter::Splitter.new
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should create a manifest builder" do
|
105
|
+
MdSplitter::ElfManifestBuilder.should_receive(:new).and_return(@duff_builder)
|
106
|
+
@subject.split "fake/path/sample.md", :split_on => "---", :manifest => true
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should pass a list of pages to the manifest builder" do
|
110
|
+
MdSplitter::ElfManifestBuilder.should_receive(:new).with(["sample_1.html", "sample_2.html", "sample_3.html"]).and_return(@duff_builder)
|
111
|
+
@subject.split "fake/path/sample.md", :split_on => "---", :manifest => true
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "saving the manifest" do
|
115
|
+
before(:each) do
|
116
|
+
MdSplitter::ElfManifestBuilder.should_receive(:new).and_return(@duff_builder)
|
117
|
+
end
|
118
|
+
it "should request the json manifest and save it to the target directory" do
|
119
|
+
@duff_builder.should_receive(:json).and_return(sample_elf_manifest)
|
120
|
+
STDOUT.should_receive(:puts).with(/Splitting/i).at_least(:once)
|
121
|
+
STDOUT.should_receive(:puts).with(/Writing fake\/path/i).at_least(:once)
|
122
|
+
STDOUT.should_receive(:puts).with(/Writing manifest/i).at_least(:once)
|
123
|
+
@subject.split "fake/path/sample.md", :split_on => "---", :manifest => true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
def make_safe_file_stubs
|
134
|
+
File.stub(:open)
|
135
|
+
FileUtils.stub(:mkpath)
|
136
|
+
end
|
137
|
+
|
138
|
+
def mock_doc_split
|
139
|
+
mock_input_file_read "fake/path/sample.md"
|
140
|
+
FileUtils.stub(:mkpath)
|
141
|
+
mock_output_file_write "fake/path/sample/sample.html", 3
|
142
|
+
# mock_output_file_write "fake/path/sample/sample_2.html"
|
143
|
+
# mock_output_file_write "fake/path/sample/sample_3.html"
|
144
|
+
# set expectations for the three calls to kramdown resulting from the split
|
145
|
+
mock_kramdown('# Heading 1').should_receive(:to_html).and_return('<h1>Heading 1</h1>')
|
146
|
+
mock_kramdown('## Heading 2').should_receive(:to_html).and_return('<h2>Heading 2</h2>')
|
147
|
+
mock_kramdown('### Heading 3').should_receive(:to_html).and_return('<h3>Heading 3</h3>')
|
148
|
+
end
|
149
|
+
|
150
|
+
def mock_kramdown text
|
151
|
+
kram_doc = double()
|
152
|
+
Kramdown::Document.should_receive(:new).with(text, :input => "kramdown", :output=> "html").and_return(kram_doc)
|
153
|
+
kram_doc
|
154
|
+
end
|
155
|
+
|
156
|
+
def mock_input_file_read file_name
|
157
|
+
# Set expectations
|
158
|
+
@stuntfile = double()
|
159
|
+
@stuntfile.should_receive(:read).and_return(sample_markdown)
|
160
|
+
File.should_receive(:open).with(file_name,"rb").and_return(@stuntfile)
|
161
|
+
end
|
162
|
+
|
163
|
+
def mock_output_file_write file_path, count = 1
|
164
|
+
file_out = double()
|
165
|
+
count.times do |t|
|
166
|
+
target_path = file_path
|
167
|
+
if count > 1
|
168
|
+
target_path = file_path.gsub(%r{(\.\w+$)}, "_#{t+1}\\1") # add _count to the file name
|
169
|
+
end
|
170
|
+
File.should_receive(:open).with(target_path, "w").and_return(file_out)
|
171
|
+
end
|
172
|
+
return
|
173
|
+
end
|
174
|
+
|
175
|
+
def simple_markdown
|
176
|
+
'# Heading'
|
177
|
+
end
|
178
|
+
|
179
|
+
def simple_html heading_level = 1
|
180
|
+
"<h#{heading_level}>Heading #{heading_level}</h#{heading_level}>"
|
181
|
+
end
|
182
|
+
|
183
|
+
def sample_markdown
|
184
|
+
<<-eos
|
185
|
+
# Heading 1
|
186
|
+
---
|
187
|
+
## Heading 2
|
188
|
+
---
|
189
|
+
### Heading 3
|
190
|
+
eos
|
191
|
+
end
|
192
|
+
|
193
|
+
def sample_elf_manifest
|
194
|
+
<<-eos
|
195
|
+
{
|
196
|
+
"id":"859d7b55-61fa-42fd-8b34-ae0f9c664bd71",
|
197
|
+
"pages":
|
198
|
+
[
|
199
|
+
{
|
200
|
+
"id":"page1",
|
201
|
+
"name":"Page 1",
|
202
|
+
"url":"page1.html"
|
203
|
+
},
|
204
|
+
{
|
205
|
+
"id":"page2",
|
206
|
+
"name":"Page 2",
|
207
|
+
"url":"page2.html"
|
208
|
+
},
|
209
|
+
{
|
210
|
+
"id":"page3",
|
211
|
+
"name":"Page 3",
|
212
|
+
"url":"page3.html"
|
213
|
+
}
|
214
|
+
]
|
215
|
+
}
|
216
|
+
eos
|
217
|
+
end
|
218
|
+
|
metadata
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: md_splitter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Darren Wallace
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-27 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70241250311920 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70241250311920
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bundler
|
27
|
+
requirement: &70241250309780 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.21
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70241250309780
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70241250308300 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.7.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70241250308300
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: guard-rspec
|
49
|
+
requirement: &70241250306780 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70241250306780
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: growl
|
60
|
+
requirement: &70241250304740 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70241250304740
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rb-fsevent
|
71
|
+
requirement: &70241250303780 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70241250303780
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: kramdown
|
82
|
+
requirement: &70241250301380 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.13.3
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70241250301380
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: commander
|
93
|
+
requirement: &70241250300160 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 4.0.6
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70241250300160
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: json
|
104
|
+
requirement: &70241250298840 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.6.1
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *70241250298840
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: uuidtools
|
115
|
+
requirement: &70241250297320 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ~>
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: 2.1.2
|
121
|
+
type: :runtime
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *70241250297320
|
124
|
+
description: Parses md docs for split markers and produces multiple html files and
|
125
|
+
a json manifest
|
126
|
+
email:
|
127
|
+
- wallace@midweekcrisis.com
|
128
|
+
executables:
|
129
|
+
- md_splitter
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- .gitignore
|
134
|
+
- .rvmrc
|
135
|
+
- Gemfile
|
136
|
+
- Guardfile
|
137
|
+
- README
|
138
|
+
- Rakefile
|
139
|
+
- bin/md_splitter
|
140
|
+
- lib/.DS_Store
|
141
|
+
- lib/md_splitter.rb
|
142
|
+
- lib/md_splitter/.DS_Store
|
143
|
+
- lib/md_splitter/elf_manifest_builder.rb
|
144
|
+
- lib/md_splitter/splitter.rb
|
145
|
+
- lib/md_splitter/version.rb
|
146
|
+
- md_splitter.gemspec
|
147
|
+
- samples/sample.md
|
148
|
+
- spec/bin/md_splitter_spec.rb
|
149
|
+
- spec/ilb/md_splitter/manifest_builder_spec.rb
|
150
|
+
- spec/ilb/md_splitter/splitter_spec.rb
|
151
|
+
homepage: ''
|
152
|
+
licenses: []
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
none: false
|
159
|
+
requirements:
|
160
|
+
- - ! '>='
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
segments:
|
164
|
+
- 0
|
165
|
+
hash: 1512417535635117458
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ! '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
segments:
|
173
|
+
- 0
|
174
|
+
hash: 1512417535635117458
|
175
|
+
requirements: []
|
176
|
+
rubyforge_project: md_splitter
|
177
|
+
rubygems_version: 1.8.10
|
178
|
+
signing_key:
|
179
|
+
specification_version: 3
|
180
|
+
summary: Prepares Markdown docs for web delivery
|
181
|
+
test_files:
|
182
|
+
- spec/bin/md_splitter_spec.rb
|
183
|
+
- spec/ilb/md_splitter/manifest_builder_spec.rb
|
184
|
+
- spec/ilb/md_splitter/splitter_spec.rb
|