bookbindery 9.5.0 → 9.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bookbinder.gemspec +3 -1
- data/lib/bookbinder/commands/collection.rb +1 -1
- data/lib/bookbinder/commands/generate.rb +1 -1
- data/lib/bookbinder/css_link_checker.rb +6 -2
- data/lib/bookbinder/preprocessing/dita_html_preprocessor.rb +3 -3
- data/lib/bookbinder/preprocessing/link_to_site_gen_dir.rb +2 -2
- data/lib/bookbinder/subnav/{json_from_html_toc.rb → navigation_entries_from_html_toc.rb} +3 -5
- data/lib/bookbinder/subnav/{json_from_markdown_toc.rb → navigation_entries_from_markdown_root.rb} +4 -4
- data/lib/bookbinder/subnav/pdf_config_creator.rb +3 -5
- data/lib/bookbinder/subnav/subnav_generator.rb +9 -6
- data/lib/bookbinder/subnav/subnav_generator_factory.rb +2 -8
- data/lib/bookbinder/subnav/template_creator.rb +33 -21
- data/master_middleman/archive_drop_down_menu.rb +3 -3
- data/master_middleman/bookbinder_helpers.rb +1 -1
- data/master_middleman/source/javascripts/sidenav.js +45 -0
- data/master_middleman/source/layouts/_additional-scripts.erb +0 -0
- data/master_middleman/source/layouts/_book-footer.erb +0 -0
- data/master_middleman/source/layouts/_book-search.erb +0 -0
- data/master_middleman/source/layouts/_book-title.erb +3 -0
- data/master_middleman/source/layouts/_header.erb +34 -0
- data/master_middleman/source/layouts/_local-header.erb +0 -0
- data/master_middleman/source/layouts/layout.erb +73 -0
- data/master_middleman/source/stylesheets/base.scss +365 -0
- data/master_middleman/source/stylesheets/partials/_book-base-values.scss +0 -0
- data/master_middleman/source/stylesheets/partials/_book-vars.scss +0 -0
- data/master_middleman/source/stylesheets/partials/_default.scss +300 -0
- data/master_middleman/source/stylesheets/partials/_footer.scss +63 -0
- data/master_middleman/source/stylesheets/partials/_header.scss +429 -0
- data/master_middleman/source/stylesheets/partials/_mixins.scss +43 -0
- data/master_middleman/source/stylesheets/partials/_reset.scss +233 -0
- data/master_middleman/source/stylesheets/partials/_search.scss +78 -0
- data/master_middleman/source/stylesheets/partials/_sidenav.scss +143 -0
- data/master_middleman/source/stylesheets/partials/_syntax-highlight.scss +64 -0
- data/master_middleman/source/stylesheets/partials/_vars.scss +62 -0
- data/master_middleman/source/subnavs/_default.erb +0 -0
- data/master_middleman/source/subnavs/_nav-links.erb +10 -0
- data/master_middleman/source/subnavs/_subnav_template.erb +8 -0
- metadata +55 -5
- data/lib/bookbinder/subnav/json_props_creator.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fce8a509ec467f42d265301238c63732c561114
|
4
|
+
data.tar.gz: 102ee2ea961254302f89115dd2c48e1e1a5fdb2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7f58749e6e832db572c4c65a2fe92decf59de7272c5c1d9c33904ce36ae3d248936a6b7c17796f1f9eef83141b84b1a356ec8c1f925653c00e579320e79cfe7
|
7
|
+
data.tar.gz: 100960ac745d0eb90ef8f7cb0cad49df23492a62fd9278aeb12773bb377cc7e3687bf89be10ba0f53a500ce3082599797a16ea9c08285d054a99e70f5d02c2d3
|
data/bookbinder.gemspec
CHANGED
@@ -2,7 +2,7 @@ require 'base64'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'bookbindery'
|
5
|
-
s.version = '9.
|
5
|
+
s.version = '9.6.0'
|
6
6
|
s.summary = 'Markdown to Rackup application documentation generator'
|
7
7
|
s.description = 'A command line utility to be run in Book repositories to stitch together their constituent Markdown repos into a static-HTML-serving application'
|
8
8
|
s.authors = ['Mike Grafton', 'Lucas Marks', 'Gavin Morgan', 'Nikhil Gajwani', 'Dan Wendorf', 'Brenda Chan', 'Matthew Boedicker', 'Andrew Bruce', 'Frank Kotsianas', 'Elena Sharma', 'Christa Hartsock', 'Michael Trestman', 'Alpha Chen', 'Sarah McAlear', 'Gregg Van Hove']
|
@@ -31,10 +31,12 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_runtime_dependency 'nokogiri', ['1.6.7.2']
|
32
32
|
s.add_runtime_dependency 'thor'
|
33
33
|
s.add_runtime_dependency 'elasticsearch'
|
34
|
+
s.add_runtime_dependency 'font-awesome-sass'
|
34
35
|
|
35
36
|
s.add_development_dependency 'license_finder'
|
36
37
|
s.add_development_dependency 'pry-byebug'
|
37
38
|
s.add_development_dependency 'rake'
|
38
39
|
s.add_development_dependency 'rspec'
|
39
40
|
s.add_development_dependency 'sendgrid-ruby'
|
41
|
+
s.add_development_dependency 'jasmine'
|
40
42
|
end
|
@@ -12,7 +12,7 @@ module Bookbinder
|
|
12
12
|
|
13
13
|
def run(name, special_bookbinder_gem_args={})
|
14
14
|
path = context_dir.join(name)
|
15
|
-
streams[:out].puts "Generating book at #{path}
|
15
|
+
streams[:out].puts "Generating book at #{path}..."
|
16
16
|
if fs.file_exist?(path)
|
17
17
|
streams[:err].puts "Cannot generate book: directory already exists"
|
18
18
|
1
|
@@ -42,14 +42,18 @@ module Bookbinder
|
|
42
42
|
case link
|
43
43
|
when data_uri then true
|
44
44
|
when remote_uri then http_reachable?(link)
|
45
|
-
when absolute_uri then File.exists?(File.join('.', 'public', link))
|
45
|
+
when absolute_uri then File.exists?(File.join('.', 'public', path_info(link)))
|
46
46
|
when relative_uri then
|
47
47
|
dirs = dirs.split('/')[0...-1]
|
48
|
-
computed_uri = File.expand_path(File.join dirs, link)
|
48
|
+
computed_uri = File.expand_path(File.join dirs, path_info(link))
|
49
49
|
File.exists?(computed_uri)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
def path_info(link)
|
54
|
+
link.sub(/[?#].+\z/, '')
|
55
|
+
end
|
56
|
+
|
53
57
|
def strip_location(id)
|
54
58
|
dirs, filepath = id.split('=> ')
|
55
59
|
[dirs, filepath]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative '../values/subnav_template'
|
2
|
-
require_relative '../../../lib/bookbinder/subnav/
|
2
|
+
require_relative '../../../lib/bookbinder/subnav/navigation_entries_from_html_toc'
|
3
3
|
|
4
4
|
module Bookbinder
|
5
5
|
module Preprocessing
|
@@ -43,7 +43,7 @@ module Bookbinder
|
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
|
-
attr_reader :fs, :subnav_gen_factory, :dita_formatter, :command_creator, :sheller, :
|
46
|
+
attr_reader :fs, :subnav_gen_factory, :dita_formatter, :command_creator, :sheller, :output_locations
|
47
47
|
|
48
48
|
def section_html_dir(section)
|
49
49
|
output_locations.html_from_preprocessing_dir.join(section.destination_directory)
|
@@ -84,7 +84,7 @@ module Bookbinder
|
|
84
84
|
|
85
85
|
|
86
86
|
def subnav_generator
|
87
|
-
@subnav_generator ||= subnav_gen_factory.produce(Subnav::
|
87
|
+
@subnav_generator ||= subnav_gen_factory.produce(Subnav::NavigationEntriesFromHtmlToc.new(fs))
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative '../subnav/subnav_generator'
|
2
|
-
require_relative '../subnav/
|
2
|
+
require_relative '../subnav/navigation_entries_from_markdown_root'
|
3
3
|
|
4
4
|
module Bookbinder
|
5
5
|
module Preprocessing
|
@@ -30,7 +30,7 @@ module Bookbinder
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def subnav_generator(require_valid_subnav_links)
|
33
|
-
@subnav_generator ||= subnav_generator_factory.produce(Subnav::
|
33
|
+
@subnav_generator ||= subnav_generator_factory.produce(Subnav::NavigationEntriesFromMarkdownRoot.new(filesystem, require_valid_subnav_links))
|
34
34
|
end
|
35
35
|
|
36
36
|
attr_reader :filesystem, :subnav_generator_factory
|
@@ -3,7 +3,7 @@ require 'active_support/all'
|
|
3
3
|
|
4
4
|
module Bookbinder
|
5
5
|
module Subnav
|
6
|
-
class
|
6
|
+
class NavigationEntriesFromHtmlToc
|
7
7
|
def initialize(fs)
|
8
8
|
@fs = fs
|
9
9
|
end
|
@@ -14,9 +14,7 @@ module Bookbinder
|
|
14
14
|
doc = parse_toc_file
|
15
15
|
set_anchor_values(doc.css('a'))
|
16
16
|
|
17
|
-
|
18
|
-
links: gather_urls_and_texts(doc.css('body > ul'))
|
19
|
-
}.to_json
|
17
|
+
gather_urls_and_texts(doc.css('body > ul'))
|
20
18
|
end
|
21
19
|
|
22
20
|
private
|
@@ -47,7 +45,7 @@ module Bookbinder
|
|
47
45
|
text = anchor.inner_text
|
48
46
|
ul = li.css('> ul')
|
49
47
|
if ul.size > 0
|
50
|
-
{url: href, text: text,
|
48
|
+
{url: href, text: text, nested_links: gather_urls_and_texts(ul)}
|
51
49
|
else
|
52
50
|
{url: href, text: text}
|
53
51
|
end
|
data/lib/bookbinder/subnav/{json_from_markdown_toc.rb → navigation_entries_from_markdown_root.rb}
RENAMED
@@ -4,7 +4,7 @@ require 'redcarpet'
|
|
4
4
|
|
5
5
|
module Bookbinder
|
6
6
|
module Subnav
|
7
|
-
class
|
7
|
+
class NavigationEntriesFromMarkdownRoot
|
8
8
|
SubnavDuplicateLinkError = Class.new(RuntimeError)
|
9
9
|
SubnavBrokenLinkError = Class.new(RuntimeError)
|
10
10
|
SubnavRootMissingError = Class.new(RuntimeError)
|
@@ -25,13 +25,13 @@ module Bookbinder
|
|
25
25
|
if @require_valid_subnav_links
|
26
26
|
raise SubnavRootMissingError.new('Subnav root not found at: ' + config.subnav_root)
|
27
27
|
else
|
28
|
-
return
|
28
|
+
return []
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
@parsed_files = {Pathname(root) => '(root)'}
|
33
33
|
|
34
|
-
|
34
|
+
gather_urls_and_texts(root)
|
35
35
|
end
|
36
36
|
|
37
37
|
attr_reader :fs, :source_for_site_gen, :renderer, :config
|
@@ -67,7 +67,7 @@ module Bookbinder
|
|
67
67
|
unless no_children
|
68
68
|
@parsed_files[next_source] = source
|
69
69
|
nested_urls_and_texts = gather_urls_and_texts(next_source)
|
70
|
-
nested_links.merge!(
|
70
|
+
nested_links.merge!(nested_links: nested_urls_and_texts) unless nested_urls_and_texts.empty?
|
71
71
|
end
|
72
72
|
|
73
73
|
{url: '/' + expanded_href.to_s, text: element.inner_text}.merge(nested_links)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'yaml'
|
2
|
-
require "json"
|
3
2
|
|
4
3
|
module Bookbinder
|
5
4
|
module Subnav
|
@@ -9,9 +8,8 @@ module Bookbinder
|
|
9
8
|
@output_locations = output_locations
|
10
9
|
end
|
11
10
|
|
12
|
-
def create(
|
13
|
-
|
14
|
-
@links = format_links(json['links'])
|
11
|
+
def create(navigation_entries, subnav_config)
|
12
|
+
@links = format_links(navigation_entries)
|
15
13
|
|
16
14
|
fs.overwrite(to: output_locations.pdf_config_dir.join(subnav_config.pdf_config),
|
17
15
|
text: config_content)
|
@@ -26,7 +24,7 @@ module Bookbinder
|
|
26
24
|
end
|
27
25
|
|
28
26
|
def format_links(links)
|
29
|
-
links.map{|item| item[
|
27
|
+
links.map{|item| item[:url] }.compact.map{|link| link.sub(/^\//, '')}
|
30
28
|
end
|
31
29
|
|
32
30
|
def config_content
|
@@ -1,22 +1,25 @@
|
|
1
1
|
module Bookbinder
|
2
2
|
module Subnav
|
3
3
|
class SubnavGenerator
|
4
|
-
def initialize(
|
5
|
-
@
|
4
|
+
def initialize(navigation_entries_parser, template_creator, pdf_config_creator, output_locations)
|
5
|
+
@navigation_entries_parser = navigation_entries_parser
|
6
6
|
@template_creator = template_creator
|
7
7
|
@pdf_config_creator = pdf_config_creator
|
8
|
+
@output_locations = output_locations
|
8
9
|
end
|
9
10
|
|
10
11
|
def generate(subnav_spec)
|
11
|
-
|
12
|
-
template_creator.create(
|
13
|
-
pdf_config_creator.create(
|
12
|
+
navigation_entries = navigation_entries_parser.get_links(subnav_spec, output_locations)
|
13
|
+
template_creator.create(navigation_entries, subnav_spec)
|
14
|
+
pdf_config_creator.create(navigation_entries, subnav_spec) if pdf?(subnav_spec)
|
14
15
|
end
|
15
16
|
|
16
|
-
attr_reader :
|
17
|
+
attr_reader :navigation_entries_parser, :template_creator, :pdf_config_creator
|
17
18
|
|
18
19
|
private
|
19
20
|
|
21
|
+
attr_reader :output_locations
|
22
|
+
|
20
23
|
def pdf?(subnav_spec)
|
21
24
|
subnav_spec.respond_to?(:pdf_config) && subnav_spec.pdf_config
|
22
25
|
end
|
@@ -1,7 +1,5 @@
|
|
1
|
-
require_relative 'json_props_creator'
|
2
1
|
require_relative 'template_creator'
|
3
2
|
require_relative 'pdf_config_creator'
|
4
|
-
require_relative '../html_document_manipulator'
|
5
3
|
|
6
4
|
module Bookbinder
|
7
5
|
module Subnav
|
@@ -12,19 +10,15 @@ module Bookbinder
|
|
12
10
|
end
|
13
11
|
|
14
12
|
def produce(json_generator)
|
15
|
-
SubnavGenerator.new(
|
13
|
+
SubnavGenerator.new(json_generator, template_creator, pdf_config_creator, output_locations)
|
16
14
|
end
|
17
15
|
|
18
16
|
attr_reader :fs, :output_locations
|
19
17
|
|
20
18
|
private
|
21
19
|
|
22
|
-
def json_props_creator(json_generator)
|
23
|
-
@json_props_creator ||= JsonPropsCreator.new(fs, output_locations, json_generator)
|
24
|
-
end
|
25
|
-
|
26
20
|
def template_creator
|
27
|
-
@template_creator ||= TemplateCreator.new(fs, output_locations
|
21
|
+
@template_creator ||= TemplateCreator.new(fs, output_locations)
|
28
22
|
end
|
29
23
|
|
30
24
|
def pdf_config_creator
|
@@ -1,24 +1,20 @@
|
|
1
|
-
|
2
|
-
require_relative '../../../lib/bookbinder/colorizer'
|
3
|
-
require_relative '../../../lib/bookbinder/terminal'
|
1
|
+
require 'erb'
|
4
2
|
|
5
3
|
module Bookbinder
|
6
4
|
module Subnav
|
7
5
|
class TemplateCreator
|
8
|
-
def initialize(fs, output_locations
|
6
|
+
def initialize(fs, output_locations)
|
9
7
|
@fs = fs
|
10
8
|
@output_locations = output_locations
|
11
|
-
@html_doc_manipulator = html_doc_manipulator
|
12
9
|
end
|
13
10
|
|
14
|
-
def create(
|
11
|
+
def create(navigation_entries, subnav_spec)
|
15
12
|
template_content = fs.read(template_path)
|
16
|
-
|
17
|
-
selector: 'div.nav-content',
|
18
|
-
attribute: 'data-props-location',
|
19
|
-
value: props_filename)
|
13
|
+
links_template = ERB.new(fs.read(subnavs_path.join('_nav-links.erb')))
|
20
14
|
|
21
|
-
|
15
|
+
populated_nav = ERB.new(template_content).result(LinkHolder.new(navigation_entries, links_template).get_binding)
|
16
|
+
|
17
|
+
fs.write(text: populated_nav, to: subnav_destination(subnav_spec.subnav_name))
|
22
18
|
end
|
23
19
|
|
24
20
|
attr_reader :fs, :output_locations, :html_doc_manipulator
|
@@ -34,21 +30,37 @@ module Bookbinder
|
|
34
30
|
end
|
35
31
|
|
36
32
|
def template_path
|
37
|
-
|
38
|
-
|
39
|
-
if deprecated_prefix
|
40
|
-
Terminal.new(Colorizer.new).update(UserMessage.new(
|
41
|
-
"Use of '_dita_subnav_template.erb' is deprecated. " +
|
42
|
-
"The preferred template is 'subnav_template.erb'. Please rename your file.",
|
43
|
-
EscalationType.warn
|
44
|
-
))
|
45
|
-
end
|
46
|
-
subnavs_path.join("#{deprecated_prefix}subnav_template.erb")
|
33
|
+
subnavs_path.join('_subnav_template.erb')
|
47
34
|
end
|
48
35
|
|
49
36
|
def subnav_destination(name)
|
50
37
|
subnavs_path.join(filename(name))
|
51
38
|
end
|
39
|
+
|
40
|
+
class LinkHolder
|
41
|
+
def initialize(links, template)
|
42
|
+
@links = links
|
43
|
+
@template = template
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :links
|
47
|
+
|
48
|
+
def get_binding
|
49
|
+
binding
|
50
|
+
end
|
51
|
+
|
52
|
+
def render_links(some_links)
|
53
|
+
@template.result(LinkHolder.new(some_links, @template).get_binding)
|
54
|
+
end
|
55
|
+
|
56
|
+
def submenu_class(link)
|
57
|
+
'has_submenu' unless links?(link[:nested_links])
|
58
|
+
end
|
59
|
+
|
60
|
+
def links?(links)
|
61
|
+
(links || []).empty?
|
62
|
+
end
|
63
|
+
end
|
52
64
|
end
|
53
65
|
end
|
54
66
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Bookbinder
|
2
2
|
class ArchiveDropDownMenu
|
3
3
|
def initialize(config, current_path: nil)
|
4
|
-
@config = config
|
4
|
+
@config = config_with_default(config)
|
5
5
|
@current_path = current_path
|
6
6
|
end
|
7
7
|
|
@@ -35,8 +35,8 @@ module Bookbinder
|
|
35
35
|
File.dirname(current_path)
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
{ root_menu_reference => empty_menu }
|
38
|
+
def config_with_default(config)
|
39
|
+
{ root_menu_reference => empty_menu }.merge(config || {})
|
40
40
|
end
|
41
41
|
|
42
42
|
def empty_menu
|
@@ -144,7 +144,7 @@ module Bookbinder
|
|
144
144
|
path = current_path.dup
|
145
145
|
end
|
146
146
|
basename = File.basename(path)
|
147
|
-
dirname = File.dirname(path).gsub(
|
147
|
+
dirname = File.dirname(path).gsub('.', '_')
|
148
148
|
page_classes(File.join(dirname, basename), options)
|
149
149
|
end
|
150
150
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
(function() {
|
2
|
+
var isExpanded = /\bexpanded\b/;
|
3
|
+
|
4
|
+
function openSubmenu(e) {
|
5
|
+
var el = e.srcElement;
|
6
|
+
if (isExpanded.test(el.className)) {
|
7
|
+
el.className = el.className.replace(isExpanded, '');
|
8
|
+
} else {
|
9
|
+
el.className += ' expanded';
|
10
|
+
}
|
11
|
+
e.stopPropagation();
|
12
|
+
}
|
13
|
+
|
14
|
+
window.Bookbinder = {
|
15
|
+
startSidenav: function(rootEl, currentPath) {
|
16
|
+
var submenus = rootEl.querySelectorAll('.has_submenu');
|
17
|
+
|
18
|
+
for (var i = 0; i < submenus.length; i++) {
|
19
|
+
submenus[i].onclick = openSubmenu;
|
20
|
+
}
|
21
|
+
|
22
|
+
if (currentPath) {
|
23
|
+
var currentLink = rootEl.querySelector('a[href="' + currentPath + '"]');
|
24
|
+
if (currentLink) {
|
25
|
+
currentLink.className += ' active';
|
26
|
+
|
27
|
+
var hasSubmenu = /\bhas_submenu\b/;
|
28
|
+
var subnavLocation = currentLink.parentNode;
|
29
|
+
|
30
|
+
while(subnavLocation.parentNode !== rootEl) {
|
31
|
+
subnavLocation = subnavLocation.parentNode;
|
32
|
+
if (hasSubmenu.test(subnavLocation.className)) {
|
33
|
+
subnavLocation.className += ' expanded';
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
rootEl.scrollTop = currentLink.offsetTop - rootEl.offsetTop;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
},
|
41
|
+
boot: function() {
|
42
|
+
Bookbinder.startSidenav(document.querySelector('#sub-nav'), document.location.pathname);
|
43
|
+
}
|
44
|
+
};
|
45
|
+
})();
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% if current_page.data.title %> <%# this is a proxy for if !homepage %>
|
2
|
+
<header class="header header-layout">
|
3
|
+
<h1 class="logo">
|
4
|
+
<a href="/"><%= vars.book_title || 'Default Book Title' %></a>
|
5
|
+
</h1>
|
6
|
+
<%= yield_for_archive_drop_down_menu %>
|
7
|
+
<div class="header-links js-bar-links">
|
8
|
+
<div class="btn-menu" data-behavior="MenuMobile"></div>
|
9
|
+
<%= vars.product_link %>
|
10
|
+
<div class="header-item">
|
11
|
+
<%= vars.support_link %>
|
12
|
+
</div>
|
13
|
+
<%= partial 'layouts/book-search' %>
|
14
|
+
</div>
|
15
|
+
</header>
|
16
|
+
<% else %>
|
17
|
+
<header class="header-home">
|
18
|
+
<div class="home-links js-bar-links">
|
19
|
+
<div class="btn-menu" data-behavior="MenuMobile"></div>
|
20
|
+
<%= vars.product_link %>
|
21
|
+
<div class="header-item">
|
22
|
+
<%= vars.support_call_to_action %>
|
23
|
+
</div>
|
24
|
+
<%= partial 'layouts/book-search' %>
|
25
|
+
</div>
|
26
|
+
<h1 class="title-flashy">
|
27
|
+
<%= partial 'layouts/book-title' %>
|
28
|
+
</h1>
|
29
|
+
|
30
|
+
<h2 class="title-intro">
|
31
|
+
<%= vars.hero_text %>
|
32
|
+
</h2>
|
33
|
+
</header>
|
34
|
+
<% end %>
|