playgroundbook 0.2.1 → 0.3.0
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 +4 -4
- data/Changelog.md +5 -0
- data/README.md +9 -1
- data/lib/playgroundbook_renderer/chapter_collator.rb +7 -25
- data/lib/playgroundbook_renderer/glossary_generator.rb +47 -0
- data/lib/playgroundbook_renderer/page_parser.rb +19 -0
- data/lib/playgroundbook_renderer/page_processor.rb +15 -0
- data/lib/playgroundbook_renderer/page_writer.rb +4 -3
- data/lib/playgroundbook_renderer/playgroundbook_renderer.rb +21 -7
- data/lib/version.rb +1 -1
- data/spec/playgroundbook_renderer_spec/chapter_collator_spec.rb +6 -6
- data/spec/playgroundbook_renderer_spec/glossary_generator_spec.rb +52 -0
- data/spec/playgroundbook_renderer_spec/page_processor_spec.rb +86 -0
- data/spec/playgroundbook_renderer_spec/page_writer_spec.rb +14 -1
- data/spec/playgroundbook_renderer_spec/playgroundbook_renderer_spec.rb +11 -1
- data/spec/spec_helper.rb +8 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cb1f23c12d4c4d5da05b5bd17d0c9309a7d9b68
|
4
|
+
data.tar.gz: 06141cc3c18eb69eb0885438b2e60ab71cc75f67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db1e4fe2b6a940c9bce9b1ebe085fb347bb2fd43efb8e422ed14a2c8e185da3e527d60e2d5ec8859e769f2cc7ba3b421d2f7520b45501e6eedee71e24f983922
|
7
|
+
data.tar.gz: f0852a23faa7728b67a1cd4cca7eda21e7174ba487cfb8b4f3dbaf889213e6405b1229ec27e7ea5523af3074fb0e8a9ab7c3174b07fc81856f12b814ed014135
|
data/Changelog.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
- Nothing yet.
|
4
4
|
|
5
|
+
# 0.3.0
|
6
|
+
|
7
|
+
- Glossary support. See [#18](https://github.com/ashfurrow/playgroundbook/issues/18).
|
8
|
+
- Removes newlines surrounding markdown blocks. See [#20](https://github.com/ashfurrow/playgroundbook/issues/20).
|
9
|
+
|
5
10
|
# 0.2.1
|
6
11
|
|
7
12
|
- Support for cover images. See [#16](https://github.com/ashfurrow/playgroundbook/issues/16).
|
data/README.md
CHANGED
@@ -39,9 +39,17 @@ chapters:
|
|
39
39
|
- Chapter 1
|
40
40
|
- Chapter 2
|
41
41
|
- etc...
|
42
|
+
glossary:
|
43
|
+
term: definition
|
42
44
|
```
|
43
45
|
|
44
|
-
Each chapter needs to have a corresponding playground; so `Chapter 1` requires there be a `Chapter 1.playground` playground. The playgrounds can reference (not copy) resources from an optionally specified directory. `import` frameworks are specified in the yaml file and are added to every page of the book. You can specify a cover image file name that's stored in the `resources` directory (it should be 400x300 pixels).
|
46
|
+
Each chapter needs to have a corresponding playground; so `Chapter 1` requires there be a `Chapter 1.playground` playground. The playgrounds can reference (not copy) resources from an optionally specified directory. `import` frameworks are specified in the yaml file and are added to every page of the book. You can specify a cover image file name that's stored in the `resources` directory (it should be 400x300 pixels). Finally, you can supply a glossary, a dictionary of term/definition pairs. This lets you link to terms in markdown. For example:
|
47
|
+
|
48
|
+
```md
|
49
|
+
... [term](glossary://term) ...
|
50
|
+
```
|
51
|
+
|
52
|
+
Only the link to the term must be URL encoded. For example, the term "reuse identifier" would be defined in the yaml as `reuse identifier` but linked to as `glossary://reuse%20identifier`.
|
45
53
|
|
46
54
|
Each chapter needs to be in the following format:
|
47
55
|
|
@@ -11,47 +11,29 @@ module Playgroundbook
|
|
11
11
|
@ui = ui
|
12
12
|
end
|
13
13
|
|
14
|
-
def collate!(chapter_name,
|
14
|
+
def collate!(chapter_name, parsed_chapter, imports)
|
15
15
|
@ui.puts "Processing #{chapter_name.green}."
|
16
16
|
|
17
17
|
chapter_directory_name = "#{chapter_name}.playgroundchapter"
|
18
18
|
Dir.mkdir(chapter_directory_name) unless Dir.exist?(chapter_directory_name)
|
19
|
-
Dir.chdir(chapter_directory_name) do
|
20
|
-
pages = parse_pages(chapter_file_contents)
|
21
|
-
|
19
|
+
Dir.chdir(chapter_directory_name) do
|
22
20
|
Dir.mkdir(PagesDirectoryName) unless Dir.exist?(PagesDirectoryName)
|
23
21
|
Dir.chdir(PagesDirectoryName) do
|
24
|
-
|
22
|
+
parsed_chapter[:page_names].each_with_index do |page_name, index|
|
25
23
|
@ui.puts " Processing #{page_name.green}."
|
26
24
|
|
27
|
-
page_contents =
|
28
|
-
page_dir_name =
|
25
|
+
page_contents = parsed_chapter[:page_contents][index]
|
26
|
+
page_dir_name = parsed_chapter[:page_dir_names][index]
|
29
27
|
|
30
28
|
@page_writer.write_page!(page_name, page_dir_name, imports, page_contents)
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
|
-
write_chapter_manifest!(chapter_name,
|
35
|
-
write_preamble!(
|
32
|
+
write_chapter_manifest!(chapter_name, parsed_chapter[:page_dir_names])
|
33
|
+
write_preamble!(parsed_chapter[:preamble])
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
|
-
def parse_pages(swift)
|
40
|
-
page_names = swift.scan(/\/\/\/\/.*$/).map { |p| p.gsub('////', '').strip }
|
41
|
-
page_dir_names = page_names.map { |p| "#{p}.playgroundpage" }
|
42
|
-
|
43
|
-
split_file = swift.split(/\/\/\/\/.*$/)
|
44
|
-
page_contents = split_file.drop(1).map { |p| p.strip }
|
45
|
-
preamble = split_file.first.strip
|
46
|
-
|
47
|
-
{
|
48
|
-
page_dir_names: page_dir_names,
|
49
|
-
page_names: page_names,
|
50
|
-
page_contents: page_contents,
|
51
|
-
preamble: preamble,
|
52
|
-
}
|
53
|
-
end
|
54
|
-
|
55
37
|
def write_chapter_manifest!(chapter_name, page_dir_names)
|
56
38
|
manifest_contents = {
|
57
39
|
'Name' => chapter_name,
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Playgroundbook
|
4
|
+
GlossaryFileName = 'Glossary.plist'.freeze
|
5
|
+
|
6
|
+
class GlossaryGenerator
|
7
|
+
def generate!(parsed_chapters, chapter_names, glossary)
|
8
|
+
glossary_plist = {
|
9
|
+
'Terms' => {}
|
10
|
+
}
|
11
|
+
|
12
|
+
glossary.each do |term, definition|
|
13
|
+
glossary_plist['Terms'][term] = { 'Definition' => definition }
|
14
|
+
escaped_term = URI.escape(term)
|
15
|
+
parsed_chapters.each_with_index do |chapter, i|
|
16
|
+
pages = chapter[:page_contents]
|
17
|
+
page_names = chapter[:page_names]
|
18
|
+
chapter_name = URI.escape(chapter_names[i])
|
19
|
+
|
20
|
+
pages.each_with_index do |page, j|
|
21
|
+
page_name = URI.escape(page_names[j])
|
22
|
+
unless page.scan("](glossary://#{escaped_term})").empty?
|
23
|
+
glossary_plist['Terms'][term].merge!({
|
24
|
+
'FirstUse' => {
|
25
|
+
'Title' => page_names[j],
|
26
|
+
'PageReference' => "#{chapter_name}/#{page_name}",
|
27
|
+
}
|
28
|
+
})
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Break if we found the first user.
|
34
|
+
break unless glossary_plist['Terms'][term]['FirstUse'].empty?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
File.open(glossary_file_name, 'w') do |file|
|
39
|
+
file.write(glossary_plist.to_plist)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def glossary_file_name
|
44
|
+
"#{ContentsDirectoryName}/#{ResourcesDirectoryName}/#{GlossaryFileName}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Playgroundbook
|
2
|
+
class PageParser
|
3
|
+
def parse_chapter_pages(chapter_contents)
|
4
|
+
page_names = chapter_contents.scan(/\/\/\/\/.*$/).map { |p| p.gsub('////', '').strip }
|
5
|
+
page_dir_names = page_names.map { |p| "#{p}.playgroundpage" }
|
6
|
+
|
7
|
+
split_file = chapter_contents.split(/\/\/\/\/.*$/)
|
8
|
+
page_contents = split_file.drop(1).map { |p| p.strip }
|
9
|
+
preamble = split_file.first.strip
|
10
|
+
|
11
|
+
{
|
12
|
+
page_dir_names: page_dir_names,
|
13
|
+
page_names: page_names,
|
14
|
+
page_contents: page_contents,
|
15
|
+
preamble: preamble,
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Playgroundbook
|
2
|
+
class PageProcessor
|
3
|
+
def strip_extraneous_newlines(page_contents)
|
4
|
+
# Three cases we need to look for:
|
5
|
+
# - Extraneous newlines before /*:
|
6
|
+
# - Extraneous newlines after */
|
7
|
+
# - Extraneous newlines either before or after //:
|
8
|
+
page_contents
|
9
|
+
.gsub(/\n+\/\*:/, "\n/*:")
|
10
|
+
.gsub(/\*\/\n+/, "*/\n")
|
11
|
+
.split(/(\/\/:.*$)\n*/).join("\n") # Important to do this before the next line, because it adds newlines before //: comments.
|
12
|
+
.gsub(/\n+\/\/:/, "\n//:")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'plist'
|
2
|
+
require 'playgroundbook_renderer/page_processor'
|
2
3
|
|
3
4
|
module Playgroundbook
|
4
5
|
class PageWriter
|
5
|
-
|
6
|
-
|
6
|
+
def initialize(page_processor = PageProcessor.new, ui = Cork::Board.new)
|
7
|
+
@page_processor = page_processor
|
7
8
|
@ui = ui
|
8
9
|
end
|
9
10
|
|
@@ -13,7 +14,7 @@ module Playgroundbook
|
|
13
14
|
contents_with_import = "//#-hidden-code\n"
|
14
15
|
contents_with_import += imports.map { |i| "import #{i}" }.join("\n") + "\n"
|
15
16
|
contents_with_import += "//#-end-hidden-code\n"
|
16
|
-
contents_with_import += page_contents
|
17
|
+
contents_with_import += @page_processor.strip_extraneous_newlines(page_contents)
|
17
18
|
|
18
19
|
Dir.chdir(page_dir_name) do
|
19
20
|
File.open(ContentsSwiftFileName, 'w') do |file|
|
@@ -4,25 +4,33 @@ require 'yaml'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'playgroundbook_renderer/contents_manifest_generator'
|
6
6
|
require 'playgroundbook_renderer/chapter_collator'
|
7
|
+
require 'playgroundbook_renderer/page_parser'
|
8
|
+
require 'playgroundbook_renderer/glossary_generator'
|
7
9
|
|
8
10
|
module Playgroundbook
|
9
|
-
|
11
|
+
ContentsDirectoryName = 'Contents'
|
10
12
|
ChaptersDirName = 'Chapters'
|
11
13
|
|
12
14
|
# A renderer for playground books.
|
13
15
|
class Renderer < AbstractLinter
|
14
16
|
attr_accessor :yaml_file_name
|
15
17
|
attr_accessor :contents_manifest_generator
|
18
|
+
attr_accessor :page_parser
|
16
19
|
attr_accessor :chapter_collator
|
20
|
+
attr_accessor :glossary_generator
|
17
21
|
attr_accessor :ui
|
18
22
|
|
19
23
|
def initialize(yaml_file_name,
|
20
|
-
contents_manifest_generator = ContentsManifestGenerator.new,
|
24
|
+
contents_manifest_generator = ContentsManifestGenerator.new,
|
25
|
+
page_parser = PageParser.new,
|
21
26
|
chapter_collator = ChapterCollator.new,
|
27
|
+
glossary_generator = GlossaryGenerator.new,
|
22
28
|
ui = Cork::Board.new)
|
23
29
|
@yaml_file_name = yaml_file_name
|
24
30
|
@contents_manifest_generator = contents_manifest_generator
|
31
|
+
@page_parser = page_parser
|
25
32
|
@chapter_collator = chapter_collator
|
33
|
+
@glossary_generator = glossary_generator
|
26
34
|
@ui = ui
|
27
35
|
end
|
28
36
|
|
@@ -41,15 +49,16 @@ module Playgroundbook
|
|
41
49
|
ui.puts 'Failed to open playground Contents.swift file.'
|
42
50
|
raise e
|
43
51
|
end
|
52
|
+
parsed_chapters = book_chapter_contents.map { |c| page_parser.parse_chapter_pages(c) }
|
44
53
|
|
45
54
|
Dir.mkdir(book_dir_name) unless Dir.exist?(book_dir_name)
|
46
55
|
Dir.chdir(book_dir_name) do
|
47
|
-
Dir.mkdir(
|
48
|
-
Dir.chdir(
|
56
|
+
Dir.mkdir(ContentsDirectoryName) unless Dir.exist?(ContentsDirectoryName)
|
57
|
+
Dir.chdir(ContentsDirectoryName) do
|
58
|
+
Dir.mkdir(ResourcesDirectoryName) unless Dir.exist?(ResourcesDirectoryName) # Always create a Resources dir, even if empty.
|
49
59
|
resources_dir = book['resources']
|
50
60
|
if !(resources_dir.nil? || resources_dir.empty?)
|
51
61
|
@ui.puts "Copying resource directory (#{resources_dir.green}) contents."
|
52
|
-
Dir.mkdir(ResourcesDirectoryName) unless Dir.exist?(ResourcesDirectoryName)
|
53
62
|
Dir.glob("../../#{resources_dir}/*").each do |file|
|
54
63
|
FileUtils.cp(file, ResourcesDirectoryName)
|
55
64
|
end
|
@@ -60,11 +69,16 @@ module Playgroundbook
|
|
60
69
|
Dir.chdir(ChaptersDirName) do
|
61
70
|
# Chapter file name becomes chapter name in playground book.
|
62
71
|
book['chapters'].each_with_index do |chapter_file_name, index|
|
63
|
-
|
64
|
-
@chapter_collator.collate!(chapter_file_name,
|
72
|
+
parsed_chapter = parsed_chapters[index]
|
73
|
+
@chapter_collator.collate!(chapter_file_name, parsed_chapter, book['imports'] || ['UIKit'])
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
77
|
+
|
78
|
+
unless book['glossary'].nil?
|
79
|
+
@ui.puts 'Generating glossary.'
|
80
|
+
@glossary_generator.generate!(parsed_chapters, book['chapters'], book['glossary'])
|
81
|
+
end
|
68
82
|
end
|
69
83
|
end
|
70
84
|
|
data/lib/version.rb
CHANGED
@@ -6,7 +6,7 @@ module Playgroundbook
|
|
6
6
|
let(:collator) { ChapterCollator.new(page_writer, test_ui) }
|
7
7
|
let(:page_writer) { double(PageWriter) }
|
8
8
|
let(:test_ui) { Cork::Board.new(silent: true) }
|
9
|
-
let(:
|
9
|
+
let(:parsed_chapter) { PageParser.new.parse_chapter_pages(test_chapter_contents) }
|
10
10
|
let(:chapter_name) { 'test_chapter' }
|
11
11
|
|
12
12
|
before do
|
@@ -14,14 +14,14 @@ module Playgroundbook
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'creates a chapter manifest' do
|
17
|
-
collator.collate!(chapter_name,
|
17
|
+
collator.collate!(chapter_name, parsed_chapter, [])
|
18
18
|
|
19
19
|
expect(File.exist?("#{chapter_name}.playgroundchapter/#{ManifestFileName}")).to be_truthy
|
20
20
|
end
|
21
21
|
|
22
22
|
context 'the chapter manifest' do
|
23
23
|
before do
|
24
|
-
collator.collate!(chapter_name,
|
24
|
+
collator.collate!(chapter_name, parsed_chapter, ['UIKit'])
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'has the correct name' do
|
@@ -40,16 +40,16 @@ module Playgroundbook
|
|
40
40
|
expect(page_writer).to receive(:write_page!).with("Page 1", "Page 1.playgroundpage", [], "str = \"Yo, it's page 1.\"\nsharedFunc()")
|
41
41
|
expect(page_writer).to receive(:write_page!).with("Page 2", "Page 2.playgroundpage", [], "str = \"Page 2 awww yeah.\"\nsharedFunc()")
|
42
42
|
|
43
|
-
collator.collate!(chapter_name,
|
43
|
+
collator.collate!(chapter_name, parsed_chapter, [])
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'does not explode if a Source directory already exists' do
|
47
|
-
expect{ collator.collate!(chapter_name,
|
47
|
+
expect{ collator.collate!(chapter_name, parsed_chapter, []) }.to_not raise_error
|
48
48
|
end
|
49
49
|
|
50
50
|
context 'having colated' do
|
51
51
|
before do
|
52
|
-
collator.collate!(chapter_name,
|
52
|
+
collator.collate!(chapter_name, parsed_chapter, [])
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'creates a Source directory if one does not exist' do
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
module Playgroundbook
|
4
|
+
describe GlossaryGenerator do
|
5
|
+
include FakeFS::SpecHelpers
|
6
|
+
let(:glossary_generator) { GlossaryGenerator.new }
|
7
|
+
let(:glossary) {{
|
8
|
+
'example term' => 'example definition'
|
9
|
+
}}
|
10
|
+
let(:glossary_file_name) { 'Contents/Resources/Glossary.plist' }
|
11
|
+
|
12
|
+
before do
|
13
|
+
FileUtils.mkdir_p('Contents/Resources')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'generates a glossary plist' do
|
17
|
+
glossary_generator.generate!({}, [], glossary)
|
18
|
+
|
19
|
+
expect(File.exist?(glossary_file_name)).to be_truthy
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'glossary plist' do
|
23
|
+
let(:glossary_plist) { Plist.parse_xml(glossary_file_name) }
|
24
|
+
|
25
|
+
it 'has a glossary with correct terms' do
|
26
|
+
glossary_generator.generate!({}, [], glossary)
|
27
|
+
|
28
|
+
expect(glossary_plist['Terms']['example term']['Definition']).to eq('example definition')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'generates correct first use page references' do
|
32
|
+
glossary_generator.generate!([
|
33
|
+
{
|
34
|
+
page_names: ['Page 1'],
|
35
|
+
page_contents: ["/*: Here's how to use [a thing](glossary://example%20term) */"],
|
36
|
+
},
|
37
|
+
{
|
38
|
+
page_names: ['Should not see this'],
|
39
|
+
page_contents: ["/*: Here's how to use [a thing](glossary://example%20term) even though this shouldn't match' */"],
|
40
|
+
}
|
41
|
+
],
|
42
|
+
['Chapter 1', 'Chapter 2'],
|
43
|
+
glossary)
|
44
|
+
|
45
|
+
expect(glossary_plist['Terms']['example term']['FirstUse']).to eq({
|
46
|
+
'PageReference' => 'Chapter%201/Page%201',
|
47
|
+
'Title' => 'Page 1'
|
48
|
+
})
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
module Playgroundbook
|
4
|
+
describe PageProcessor do
|
5
|
+
let(:page_processor) { PageProcessor.new }
|
6
|
+
|
7
|
+
it 'removes newlines before markdown blocks' do
|
8
|
+
page_contents = <<-EOS
|
9
|
+
let a = 6
|
10
|
+
|
11
|
+
/*:
|
12
|
+
Some markdown.
|
13
|
+
*/
|
14
|
+
EOS
|
15
|
+
processed_page_contents = <<-EOS
|
16
|
+
let a = 6
|
17
|
+
/*:
|
18
|
+
Some markdown.
|
19
|
+
*/
|
20
|
+
EOS
|
21
|
+
|
22
|
+
expect(page_processor.strip_extraneous_newlines(page_contents)).to eq(processed_page_contents)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'removes newlines after markdown blocks' do
|
26
|
+
page_contents = <<-EOS
|
27
|
+
/*:
|
28
|
+
Some markdown.
|
29
|
+
*/
|
30
|
+
|
31
|
+
let a = 6
|
32
|
+
EOS
|
33
|
+
processed_page_contents = <<-EOS
|
34
|
+
/*:
|
35
|
+
Some markdown.
|
36
|
+
*/
|
37
|
+
let a = 6
|
38
|
+
EOS
|
39
|
+
|
40
|
+
expect(page_processor.strip_extraneous_newlines(page_contents)).to eq(processed_page_contents)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'removes newlines surrounding single-line markdown blocks' do
|
44
|
+
page_contents = <<-EOS
|
45
|
+
let a = 6
|
46
|
+
|
47
|
+
//: Some markdown.
|
48
|
+
|
49
|
+
let b = a
|
50
|
+
EOS
|
51
|
+
processed_page_contents = <<-EOS
|
52
|
+
let a = 6
|
53
|
+
//: Some markdown.
|
54
|
+
let b = a
|
55
|
+
EOS
|
56
|
+
|
57
|
+
expect(page_processor.strip_extraneous_newlines(page_contents)).to eq(processed_page_contents)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not strip newlines from code' do
|
61
|
+
page_contents = <<-EOS
|
62
|
+
let a = 6
|
63
|
+
|
64
|
+
let b = a
|
65
|
+
EOS
|
66
|
+
|
67
|
+
expect(page_processor.strip_extraneous_newlines(page_contents)).to eq(page_contents)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'it does not strip newlines from the markdown' do
|
71
|
+
page_contents = <<-EOS
|
72
|
+
/*:
|
73
|
+
|
74
|
+
# Header
|
75
|
+
|
76
|
+
Some markdown. The following lines are purposefull left blank.
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
*/
|
81
|
+
EOS
|
82
|
+
|
83
|
+
expect(page_processor.strip_extraneous_newlines(page_contents)).to eq(page_contents)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -3,13 +3,21 @@ require File.expand_path('../../spec_helper', __FILE__)
|
|
3
3
|
module Playgroundbook
|
4
4
|
describe PageWriter do
|
5
5
|
include FakeFS::SpecHelpers
|
6
|
-
let(:page_writer) { PageWriter.new(test_ui) }
|
6
|
+
let(:page_writer) { PageWriter.new(page_processor, test_ui) }
|
7
|
+
let(:page_processor) { double(PageProcessor) }
|
7
8
|
let(:test_ui) { Cork::Board.new(silent: true) }
|
8
9
|
let(:page_name) { 'test page name' }
|
9
10
|
let(:page_dir_name) { 'test page name.playgroundpage' }
|
10
11
|
let(:page_contents) { "// Some swift goes here." }
|
11
12
|
let(:generated_page_contesnts) { "//#-hidden-code\nimport UIKit\n//#-end-hidden-code\n// Some swift goes here." }
|
12
13
|
|
14
|
+
before do
|
15
|
+
allow(page_processor).to receive(:strip_extraneous_newlines) do |page_contents|
|
16
|
+
# Returns the parameter, unprocessed.
|
17
|
+
page_contents
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
13
21
|
context 'with a pre-existing page directory' do
|
14
22
|
before do
|
15
23
|
Dir.mkdir(page_dir_name)
|
@@ -20,6 +28,11 @@ module Playgroundbook
|
|
20
28
|
end
|
21
29
|
end
|
22
30
|
|
31
|
+
it 'calls the page processor' do
|
32
|
+
expect(page_processor).to receive(:strip_extraneous_newlines)
|
33
|
+
page_writer.write_page!(page_name, page_dir_name, ['UIKit'], page_contents)
|
34
|
+
end
|
35
|
+
|
23
36
|
context 'as a consequence of writing rendering' do
|
24
37
|
before do
|
25
38
|
page_writer.write_page!(page_name, page_dir_name, ['UIKit'], page_contents)
|
@@ -3,10 +3,12 @@ require File.expand_path('../../spec_helper', __FILE__)
|
|
3
3
|
module Playgroundbook
|
4
4
|
describe Renderer do
|
5
5
|
include FakeFS::SpecHelpers
|
6
|
-
let(:renderer) { Renderer.new(yaml_file_name, contents_manifest_generator, chapter_collator, test_ui) }
|
6
|
+
let(:renderer) { Renderer.new(yaml_file_name, contents_manifest_generator, page_parser, chapter_collator, glossary_generator, test_ui) }
|
7
7
|
let(:yaml_file_name) { 'book.yml' }
|
8
8
|
let(:contents_manifest_generator) { double(ContentsManifestGenerator) }
|
9
|
+
let(:page_parser) { double(PageParser) }
|
9
10
|
let(:chapter_collator) { double(ChapterCollator) }
|
11
|
+
let(:glossary_generator) { double(GlossaryGenerator) }
|
10
12
|
let(:test_ui) { Cork::Board.new(silent: true) }
|
11
13
|
|
12
14
|
before do
|
@@ -16,6 +18,7 @@ module Playgroundbook
|
|
16
18
|
|
17
19
|
allow(contents_manifest_generator).to receive(:generate!)
|
18
20
|
allow(chapter_collator).to receive(:collate!)
|
21
|
+
allow(glossary_generator).to receive(:generate!)
|
19
22
|
end
|
20
23
|
|
21
24
|
it 'initializes correctly' do
|
@@ -28,6 +31,7 @@ module Playgroundbook
|
|
28
31
|
|
29
32
|
context 'with a playground' do
|
30
33
|
before do
|
34
|
+
allow(page_parser).to receive(:parse_chapter_pages)
|
31
35
|
Dir.mkdir('assets')
|
32
36
|
FileUtils.touch('assets/file.png')
|
33
37
|
Dir.mkdir('test_chapter.playground/')
|
@@ -107,6 +111,12 @@ module Playgroundbook
|
|
107
111
|
end
|
108
112
|
end
|
109
113
|
end
|
114
|
+
|
115
|
+
it 'generates a glossary' do
|
116
|
+
expect(glossary_generator).to receive(:generate!)
|
117
|
+
|
118
|
+
renderer.render!
|
119
|
+
end
|
110
120
|
end
|
111
121
|
end
|
112
122
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -24,6 +24,9 @@ require 'playgroundbook_lint/root_manifest_linter'
|
|
24
24
|
require 'playgroundbook_renderer/contents_manifest_generator'
|
25
25
|
require 'playgroundbook_renderer/chapter_collator'
|
26
26
|
require 'playgroundbook_renderer/page_writer'
|
27
|
+
require 'playgroundbook_renderer/page_parser'
|
28
|
+
require 'playgroundbook_renderer/glossary_generator'
|
29
|
+
require 'playgroundbook_renderer/page_processor'
|
27
30
|
|
28
31
|
RSpec.configure do |config|
|
29
32
|
config.color = true
|
@@ -46,6 +49,11 @@ def test_book_metadata
|
|
46
49
|
'identifier' => 'com.ashfurrow.testing',
|
47
50
|
'resources' => 'assets',
|
48
51
|
'cover' => 'file.jpeg',
|
52
|
+
'glossary' => [
|
53
|
+
{
|
54
|
+
'term' => 'definition'
|
55
|
+
}
|
56
|
+
]
|
49
57
|
}
|
50
58
|
end
|
51
59
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playgroundbook
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ash Furrow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: plist
|
@@ -85,6 +85,9 @@ files:
|
|
85
85
|
- lib/playgroundbook_lint/root_manifest_linter.rb
|
86
86
|
- lib/playgroundbook_renderer/chapter_collator.rb
|
87
87
|
- lib/playgroundbook_renderer/contents_manifest_generator.rb
|
88
|
+
- lib/playgroundbook_renderer/glossary_generator.rb
|
89
|
+
- lib/playgroundbook_renderer/page_parser.rb
|
90
|
+
- lib/playgroundbook_renderer/page_processor.rb
|
88
91
|
- lib/playgroundbook_renderer/page_writer.rb
|
89
92
|
- lib/playgroundbook_renderer/playgroundbook_renderer.rb
|
90
93
|
- lib/version.rb
|
@@ -111,6 +114,8 @@ files:
|
|
111
114
|
- spec/playground_book_lint/root_manifest_linter_spec.rb
|
112
115
|
- spec/playgroundbook_renderer_spec/chapter_collator_spec.rb
|
113
116
|
- spec/playgroundbook_renderer_spec/contents_manfiest_generator_spec.rb
|
117
|
+
- spec/playgroundbook_renderer_spec/glossary_generator_spec.rb
|
118
|
+
- spec/playgroundbook_renderer_spec/page_processor_spec.rb
|
114
119
|
- spec/playgroundbook_renderer_spec/page_writer_spec.rb
|
115
120
|
- spec/playgroundbook_renderer_spec/playgroundbook_renderer_spec.rb
|
116
121
|
- spec/spec_helper.rb
|