alb-test 10.1.15
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/bookbinder.gemspec +46 -0
- data/install_bin/bookbinder +5 -0
- data/lib/bookbinder/cli.rb +105 -0
- data/lib/bookbinder/code_example_reader.rb +95 -0
- data/lib/bookbinder/colorizer.rb +16 -0
- data/lib/bookbinder/commands/bind.rb +120 -0
- data/lib/bookbinder/commands/collection.rb +181 -0
- data/lib/bookbinder/commands/components/bind/directory_preparer.rb +33 -0
- data/lib/bookbinder/commands/components/bind/layout_preparer.rb +27 -0
- data/lib/bookbinder/commands/components/command_options.rb +45 -0
- data/lib/bookbinder/commands/components/imprint/directory_preparer.rb +24 -0
- data/lib/bookbinder/commands/generate.rb +92 -0
- data/lib/bookbinder/commands/imprint.rb +55 -0
- data/lib/bookbinder/commands/punch.rb +33 -0
- data/lib/bookbinder/commands/update_local_doc_repos.rb +42 -0
- data/lib/bookbinder/commands/watch.rb +100 -0
- data/lib/bookbinder/config/checkers/archive_menu_checker.rb +29 -0
- data/lib/bookbinder/config/checkers/ditamap_presence_checker.rb +27 -0
- data/lib/bookbinder/config/checkers/duplicate_section_name_checker.rb +33 -0
- data/lib/bookbinder/config/checkers/products_checker.rb +34 -0
- data/lib/bookbinder/config/checkers/repository_name_presence_checker.rb +34 -0
- data/lib/bookbinder/config/checkers/required_keys_checker.rb +18 -0
- data/lib/bookbinder/config/checkers/section_presence_checker.rb +15 -0
- data/lib/bookbinder/config/configuration.rb +119 -0
- data/lib/bookbinder/config/configuration_decorator.rb +54 -0
- data/lib/bookbinder/config/dita_config_generator.rb +61 -0
- data/lib/bookbinder/config/fetcher.rb +64 -0
- data/lib/bookbinder/config/imprint/configuration.rb +24 -0
- data/lib/bookbinder/config/product_config.rb +34 -0
- data/lib/bookbinder/config/section_config.rb +85 -0
- data/lib/bookbinder/config/validator.rb +33 -0
- data/lib/bookbinder/config/yaml_loader.rb +34 -0
- data/lib/bookbinder/css_link_checker.rb +67 -0
- data/lib/bookbinder/directory_helpers.rb +15 -0
- data/lib/bookbinder/dita_command_creator.rb +95 -0
- data/lib/bookbinder/dita_html_for_middleman_formatter.rb +45 -0
- data/lib/bookbinder/errors/programmer_mistake.rb +5 -0
- data/lib/bookbinder/html_document_manipulator.rb +21 -0
- data/lib/bookbinder/ingest/cloner_factory.rb +26 -0
- data/lib/bookbinder/ingest/destination_directory.rb +21 -0
- data/lib/bookbinder/ingest/git_accessor.rb +102 -0
- data/lib/bookbinder/ingest/git_cloner.rb +36 -0
- data/lib/bookbinder/ingest/local_filesystem_cloner.rb +66 -0
- data/lib/bookbinder/ingest/missing_working_copy.rb +27 -0
- data/lib/bookbinder/ingest/repo_identifier.rb +45 -0
- data/lib/bookbinder/ingest/section_repository.rb +49 -0
- data/lib/bookbinder/ingest/update_failure.rb +15 -0
- data/lib/bookbinder/ingest/update_success.rb +12 -0
- data/lib/bookbinder/ingest/working_copy.rb +36 -0
- data/lib/bookbinder/local_filesystem_accessor.rb +122 -0
- data/lib/bookbinder/middleman_runner.rb +50 -0
- data/lib/bookbinder/postprocessing/link_checker.rb +125 -0
- data/lib/bookbinder/postprocessing/redirection.rb +38 -0
- data/lib/bookbinder/preprocessing/dita_html_preprocessor.rb +91 -0
- data/lib/bookbinder/preprocessing/dita_pdf_preprocessor.rb +48 -0
- data/lib/bookbinder/preprocessing/link_to_site_gen_dir.rb +39 -0
- data/lib/bookbinder/preprocessing/preprocessor.rb +26 -0
- data/lib/bookbinder/server_director.rb +30 -0
- data/lib/bookbinder/sheller.rb +52 -0
- data/lib/bookbinder/streams/colorized_stream.rb +25 -0
- data/lib/bookbinder/streams/filter_stream.rb +22 -0
- data/lib/bookbinder/subnav/navigation_entries_from_html_toc.rb +59 -0
- data/lib/bookbinder/subnav/navigation_entries_from_markdown_root.rb +116 -0
- data/lib/bookbinder/subnav/pdf_config_creator.rb +50 -0
- data/lib/bookbinder/subnav/subnav_generator.rb +28 -0
- data/lib/bookbinder/subnav/subnav_generator_factory.rb +29 -0
- data/lib/bookbinder/subnav/template_creator.rb +71 -0
- data/lib/bookbinder/terminal.rb +19 -0
- data/lib/bookbinder/values/output_locations.rb +91 -0
- data/lib/bookbinder/values/product_info.rb +11 -0
- data/lib/bookbinder/values/section.rb +58 -0
- data/lib/bookbinder/values/subnav_template.rb +4 -0
- data/lib/bookbinder/values/user_message.rb +15 -0
- data/master_middleman/archive_drop_down_menu.rb +50 -0
- data/master_middleman/bookbinder_helpers.rb +282 -0
- data/master_middleman/compass_runner.rb +0 -0
- data/master_middleman/config.rb +45 -0
- data/master_middleman/proof.rb +90 -0
- data/master_middleman/quicklinks_renderer.rb +80 -0
- data/master_middleman/source/javascripts/all.js +2 -0
- data/master_middleman/source/javascripts/book.js +1 -0
- data/master_middleman/source/javascripts/bookbinder.js +130 -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/_page-footer.erb +1 -0
- data/master_middleman/source/layouts/_title.erb +5 -0
- data/master_middleman/source/layouts/layout.erb +70 -0
- data/master_middleman/source/stylesheets/all.css.scss +3 -0
- data/master_middleman/source/stylesheets/base.scss +324 -0
- data/master_middleman/source/stylesheets/book-styles.scss +0 -0
- data/master_middleman/source/stylesheets/layout-styles.scss +0 -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 +302 -0
- data/master_middleman/source/stylesheets/partials/_footer.scss +64 -0
- data/master_middleman/source/stylesheets/partials/_header.scss +419 -0
- data/master_middleman/source/stylesheets/partials/_layout-vars.scss +0 -0
- data/master_middleman/source/stylesheets/partials/_mixins.scss +53 -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 +191 -0
- data/master_middleman/source/stylesheets/partials/_syntax-highlight.scss +64 -0
- data/master_middleman/source/stylesheets/partials/_vars.scss +64 -0
- data/master_middleman/source/stylesheets/print-book-styles.scss +0 -0
- data/master_middleman/source/stylesheets/print-layout-styles.scss +0 -0
- data/master_middleman/source/stylesheets/print.css.scss +57 -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
- data/master_middleman/subdirectory_aware_assets.rb +36 -0
- data/template_app/Gemfile +10 -0
- data/template_app/Gemfile.lock +49 -0
- data/template_app/config.ru +9 -0
- data/template_app/lib/rack_static_if_exists.rb +19 -0
- data/template_app/lib/search/handler.rb +73 -0
- data/template_app/lib/search/hit.rb +21 -0
- data/template_app/lib/search/query.rb +74 -0
- data/template_app/lib/search/renderer.rb +30 -0
- data/template_app/lib/server.rb +52 -0
- data/template_app/mail_sender.rb +61 -0
- data/template_app/rack_app.rb +110 -0
- data/template_app/search-results.html.erb +81 -0
- data/template_app/search.yml +23 -0
- metadata +548 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require_relative 'template_creator'
|
|
2
|
+
require_relative 'pdf_config_creator'
|
|
3
|
+
|
|
4
|
+
module Bookbinder
|
|
5
|
+
module Subnav
|
|
6
|
+
class SubnavGeneratorFactory
|
|
7
|
+
def initialize(fs, output_locations)
|
|
8
|
+
@fs = fs
|
|
9
|
+
@output_locations = output_locations
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def produce(json_generator)
|
|
13
|
+
SubnavGenerator.new(json_generator, template_creator, pdf_config_creator, output_locations)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :fs, :output_locations
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def template_creator
|
|
21
|
+
@template_creator ||= TemplateCreator.new(fs, output_locations)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def pdf_config_creator
|
|
25
|
+
@pdf_config_creator ||= PdfConfigCreator.new(fs, output_locations)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
require 'rack/utils'
|
|
3
|
+
|
|
4
|
+
module Bookbinder
|
|
5
|
+
module Subnav
|
|
6
|
+
class TemplateCreator
|
|
7
|
+
def initialize(fs, output_locations)
|
|
8
|
+
@fs = fs
|
|
9
|
+
@output_locations = output_locations
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create(navigation_entries, subnav_spec)
|
|
13
|
+
template_content = fs.read(template_path)
|
|
14
|
+
links_template = ERB.new(fs.read(subnavs_path.join('_nav-links.erb')))
|
|
15
|
+
|
|
16
|
+
populated_nav = ERB.new(template_content).result(LinkHolder.new(navigation_entries, links_template).get_binding)
|
|
17
|
+
|
|
18
|
+
fs.write(text: populated_nav, to: subnav_destination(subnav_spec.subnav_name))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
attr_reader :fs, :output_locations, :html_doc_manipulator
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def subnavs_path
|
|
26
|
+
output_locations.subnavs_for_layout_dir
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def filename(name)
|
|
30
|
+
"#{name}.erb"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def template_path
|
|
34
|
+
subnavs_path.join('_subnav_template.erb')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def subnav_destination(name)
|
|
38
|
+
subnavs_path.join(filename(name))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class LinkHolder
|
|
42
|
+
def initialize(links, template)
|
|
43
|
+
@links = links
|
|
44
|
+
@template = template
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attr_reader :links
|
|
48
|
+
|
|
49
|
+
def get_binding
|
|
50
|
+
binding
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def render_links(some_links)
|
|
54
|
+
@template.result(LinkHolder.new(some_links, @template).get_binding)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def submenu_class(link)
|
|
58
|
+
'has_submenu' unless links?(link[:nested_links])
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def links?(links)
|
|
62
|
+
(links || []).empty?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def escape_html(str)
|
|
66
|
+
Rack::Utils.escape_html(str)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative 'colorizer'
|
|
2
|
+
|
|
3
|
+
module Bookbinder
|
|
4
|
+
class Terminal
|
|
5
|
+
def initialize(colorizer)
|
|
6
|
+
@colorizer = colorizer
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def update(user_message)
|
|
10
|
+
if user_message.error?
|
|
11
|
+
error_message = @colorizer.colorize(user_message.message, Colorizer::Colors.red)
|
|
12
|
+
$stderr.puts error_message
|
|
13
|
+
elsif user_message.warn?
|
|
14
|
+
warning_message = @colorizer.colorize(user_message.message, Colorizer::Colors.yellow)
|
|
15
|
+
puts warning_message
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require_relative '../directory_helpers'
|
|
2
|
+
require_relative '../errors/programmer_mistake'
|
|
3
|
+
|
|
4
|
+
module Bookbinder
|
|
5
|
+
class OutputLocations
|
|
6
|
+
include DirectoryHelperMethods
|
|
7
|
+
|
|
8
|
+
def initialize(final_app_dir: nil, context_dir: nil)
|
|
9
|
+
@final_app_dir = final_app_dir
|
|
10
|
+
@context_dir = context_dir
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def final_app_dir
|
|
14
|
+
Pathname(@final_app_dir)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def public_dir
|
|
18
|
+
final_app_dir.join('public')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def build_dir
|
|
22
|
+
master_dir.join('build/.')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def workspace_dir
|
|
26
|
+
master_dir.join('source')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def master_dir
|
|
30
|
+
output_dir.join('master_middleman')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def output_dir
|
|
34
|
+
context_dir.join(output_dir_name)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def preprocessing_home_dir
|
|
38
|
+
output_dir.join('preprocessing')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def cloned_preprocessing_dir
|
|
42
|
+
preprocessing_home_dir.join('sections')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def html_from_preprocessing_dir
|
|
46
|
+
preprocessing_home_dir.join('html_from_preprocessing')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def pdf_from_preprocessing_dir
|
|
50
|
+
preprocessing_home_dir.join('pdf_from_preprocessing')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def formatted_dir
|
|
54
|
+
preprocessing_home_dir.join('site_generator_ready')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def site_generator_home
|
|
58
|
+
output_dir.join('master_middleman')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def source_for_site_generator
|
|
62
|
+
site_generator_home.join('source')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def subnavs_for_layout_dir
|
|
66
|
+
source_for_site_generator.join('subnavs')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def pdf_config_dir
|
|
70
|
+
context_dir
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def artifact_dir
|
|
74
|
+
context_dir.join('artifacts')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def pdf_artifact_dir
|
|
78
|
+
artifact_dir.join('pdfs')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def context_dir
|
|
84
|
+
if @context_dir.nil?
|
|
85
|
+
raise Errors::ProgrammerMistake.new("You must provide a context_dir to OutputLocations")
|
|
86
|
+
else
|
|
87
|
+
Pathname(@context_dir)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative '../errors/programmer_mistake'
|
|
2
|
+
require_relative '../ingest/destination_directory'
|
|
3
|
+
|
|
4
|
+
module Bookbinder
|
|
5
|
+
Section = Struct.new(
|
|
6
|
+
:path_to_repository,
|
|
7
|
+
:full_name,
|
|
8
|
+
:desired_directory_name,
|
|
9
|
+
:subnav_templ,
|
|
10
|
+
:desired_subnav_name,
|
|
11
|
+
:preprocessor_config,
|
|
12
|
+
:at_repo_path,
|
|
13
|
+
:repo_name,
|
|
14
|
+
:source_ref,
|
|
15
|
+
:pdf_output_filename,
|
|
16
|
+
:product_info) do
|
|
17
|
+
|
|
18
|
+
def path_to_repo_dir
|
|
19
|
+
at_repo_path.nil? ? path_to_repository : path_to_repository.join(at_repo_path)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def subnav_template
|
|
23
|
+
subnav_templ.sub(/^_/, '').sub(/\.erb$/, '') if subnav_templ
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def destination_directory
|
|
27
|
+
Ingest::DestinationDirectory.new(full_name, desired_directory_name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def subnav
|
|
31
|
+
{namespace => subnav_name}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def namespace
|
|
35
|
+
destination_directory.to_s.gsub(%r{[./]}, '_')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def subnav_name
|
|
39
|
+
subnav_template || desired_subnav_name || 'default'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def path_to_preprocessor_attribute(attr)
|
|
43
|
+
path_to_repo_dir.join(preprocessor_config[attr]) if preprocessor_config[attr]
|
|
44
|
+
rescue NoMethodError => e
|
|
45
|
+
raise Errors::ProgrammerMistake.new(
|
|
46
|
+
"path_to_preprocessor_attribute assumes preprocessor_config is available, got nil.\n" +
|
|
47
|
+
"Original exception:\n\n#{e.inspect}\n\n#{e.backtrace.join("\n")}"
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def path_to_repository
|
|
54
|
+
Pathname(self[:path_to_repository].to_s)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
|
|
3
|
+
module Bookbinder
|
|
4
|
+
UserMessage = Struct.new(:message, :escalation_type) do
|
|
5
|
+
def error?
|
|
6
|
+
escalation_type == EscalationType.error
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def warn?
|
|
10
|
+
escalation_type == EscalationType.warn
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
EscalationType = OpenStruct.new(success: 0, error: 1, warn: 2)
|
|
15
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Bookbinder
|
|
2
|
+
class ArchiveDropDownMenu
|
|
3
|
+
def initialize(config, current_path: nil)
|
|
4
|
+
@config = config_with_default(config)
|
|
5
|
+
@current_path = current_path
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def title
|
|
9
|
+
directory_config.first
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dropdown_links
|
|
13
|
+
versions_to_paths.map { |version_path|
|
|
14
|
+
{version_path.keys.first => "/#{version_path.values.first}"}
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def empty?
|
|
19
|
+
title.nil? && dropdown_links.empty?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
attr_reader :config, :current_path
|
|
25
|
+
|
|
26
|
+
def versions_to_paths
|
|
27
|
+
directory_config[1..-1]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def directory_config
|
|
31
|
+
config.fetch(directory, config.fetch(root_menu_reference)) || empty_menu
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def directory
|
|
35
|
+
File.dirname(current_path)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def config_with_default(config)
|
|
39
|
+
{ root_menu_reference => empty_menu }.merge(config || {})
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def empty_menu
|
|
43
|
+
[nil]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def root_menu_reference
|
|
47
|
+
'.'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
require 'bookbinder/code_example_reader'
|
|
2
|
+
require 'bookbinder/ingest/cloner_factory'
|
|
3
|
+
require 'bookbinder/ingest/git_accessor'
|
|
4
|
+
require 'bookbinder/local_filesystem_accessor'
|
|
5
|
+
require 'date'
|
|
6
|
+
require_relative 'archive_drop_down_menu'
|
|
7
|
+
require_relative 'quicklinks_renderer'
|
|
8
|
+
|
|
9
|
+
I18n.enforce_available_locales = false
|
|
10
|
+
|
|
11
|
+
module Bookbinder
|
|
12
|
+
class Helpers < ::Middleman::Extension
|
|
13
|
+
# class << self
|
|
14
|
+
# def registered(app)
|
|
15
|
+
# app.helpers HelperMethods
|
|
16
|
+
# end
|
|
17
|
+
|
|
18
|
+
# alias :included :registered
|
|
19
|
+
# end
|
|
20
|
+
|
|
21
|
+
module HelperMethods
|
|
22
|
+
|
|
23
|
+
def yield_for_code_snippet(from: nil, at: nil)
|
|
24
|
+
cloner_factory = Ingest::ClonerFactory.new({out: $stdout},
|
|
25
|
+
LocalFilesystemAccessor.new,
|
|
26
|
+
Ingest::GitAccessor.new)
|
|
27
|
+
|
|
28
|
+
cloner = cloner_factory.produce(config[:local_repo_dir])
|
|
29
|
+
code_example_reader = CodeExampleReader.new({out: $stdout},
|
|
30
|
+
LocalFilesystemAccessor.new)
|
|
31
|
+
working_copy = cloner.call(source_repo_name: from,
|
|
32
|
+
source_ref: 'master',
|
|
33
|
+
destination_parent_dir: config[:workspace])
|
|
34
|
+
|
|
35
|
+
snippet, language = code_example_reader.get_snippet_and_language_at(at, working_copy)
|
|
36
|
+
|
|
37
|
+
delimiter = '```'
|
|
38
|
+
|
|
39
|
+
snippet.prepend("#{delimiter}#{language}\n").concat("\n#{delimiter}")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def elastic_search?
|
|
43
|
+
!!config[:elastic_search]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def yield_for_subnav
|
|
47
|
+
partial "subnavs/#{subnav_template_name}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def yield_for_archive_drop_down_menu
|
|
51
|
+
menu = ArchiveDropDownMenu.new(
|
|
52
|
+
config[:archive_menu],
|
|
53
|
+
current_path: current_page.path
|
|
54
|
+
)
|
|
55
|
+
unless menu.empty?
|
|
56
|
+
partial 'archive_menus/default', locals: { menu_title: menu.title,
|
|
57
|
+
dropdown_links: menu.dropdown_links }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def exclude_feedback
|
|
62
|
+
current_page.add_metadata({page: {feedback_disabled: true}})
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def yield_for_feedback
|
|
66
|
+
partial 'layouts/feedback' if config[:feedback_enabled] && !current_page.metadata[:page][:feedback_disabled]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def exclude_repo_link
|
|
70
|
+
current_page.add_metadata({page: {repo_link_disabled: true}})
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def render_repo_link
|
|
74
|
+
if config[:repo_link_enabled] && repo_url && !current_page.metadata[:page][:repo_link_disabled]
|
|
75
|
+
"<a id='repo-link' href='#{repo_url}'>Create a pull request or raise an issue on the source for this page in GitHub</a>"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def mermaid_diagram(&blk)
|
|
80
|
+
escaped_text = capture(&blk).gsub('-','\-')
|
|
81
|
+
|
|
82
|
+
@_out_buf.concat "<div class='mermaid'>#{escaped_text}</div>"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def modified_date(default_date: nil)
|
|
86
|
+
parsed_default_date = Time.parse(default_date).utc if default_date
|
|
87
|
+
|
|
88
|
+
date = page_last_modified_date || parsed_default_date
|
|
89
|
+
|
|
90
|
+
"Page last updated: <span data-behavior=\"DisplayModifiedDate\" data-modified-date=\"#{date.to_i}000\"></span>" if date
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def breadcrumbs
|
|
94
|
+
page_chain = add_ancestors_of(current_page, [])
|
|
95
|
+
breadcrumbs = page_chain.map do |page|
|
|
96
|
+
make_breadcrumb(page, page == current_page)
|
|
97
|
+
end.compact
|
|
98
|
+
return if breadcrumbs.size < 2
|
|
99
|
+
return content_tag :ul, breadcrumbs.reverse.join(' '), class: 'breadcrumbs'
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def vars
|
|
103
|
+
OpenStruct.new config[:template_variables]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def product_name
|
|
107
|
+
return vars.product_name
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def product_name_long
|
|
111
|
+
return vars.product_name_long
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def product_version
|
|
115
|
+
return vars.product_version
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def set_title(*args)
|
|
119
|
+
current_page.data.title= args.join(' ')
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def set_title_no_spaces(*args)
|
|
123
|
+
current_page.data.title= args.join
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def product_info
|
|
127
|
+
config[:product_info].fetch(template_key, {})
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def production_host
|
|
131
|
+
config[:production_host]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def quick_links
|
|
135
|
+
page_src = File.read(current_page.source_file)
|
|
136
|
+
quicklinks_renderer = QuicklinksRenderer.new(vars)
|
|
137
|
+
Redcarpet::Markdown.new(quicklinks_renderer).render(page_src)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def owners
|
|
141
|
+
html_resources = sitemap.resources.select { |r| r.path.end_with?('.html') }
|
|
142
|
+
html_resources.each.with_object({}) { |resource, owners|
|
|
143
|
+
owners[resource.path] = Array(resource.data['owner'])
|
|
144
|
+
}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def template_key
|
|
148
|
+
decreasingly_specific_namespaces.detect { |ns|
|
|
149
|
+
config[:subnav_templates].has_key?(ns)
|
|
150
|
+
}
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def body_classes(path=current_path.dup, options={})
|
|
154
|
+
if path.is_a? Hash
|
|
155
|
+
options = path
|
|
156
|
+
path = current_path.dup
|
|
157
|
+
end
|
|
158
|
+
basename = File.basename(path)
|
|
159
|
+
dirname = File.dirname(path).gsub('.', '_')
|
|
160
|
+
page_classes(File.join(dirname, basename), options)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
private
|
|
164
|
+
|
|
165
|
+
def subnav_template_name
|
|
166
|
+
config[:subnav_templates][template_key] || 'default'
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def decreasingly_specific_namespaces
|
|
170
|
+
body_classes(numeric_prefix: numeric_class_prefix).
|
|
171
|
+
split(' ').reverse.drop(1).
|
|
172
|
+
map {|ns| ns.sub(/^#{numeric_class_prefix}/, '')}
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def numeric_class_prefix
|
|
176
|
+
'NUMERIC_CLASS_PREFIX'
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def page_last_modified_date
|
|
180
|
+
git_accessor = Ingest::GitAccessor.new
|
|
181
|
+
|
|
182
|
+
current_date = if current_page.data.dita
|
|
183
|
+
git_accessor.author_date(preprocessing_path(current_page.source_file), dita: true)
|
|
184
|
+
else
|
|
185
|
+
git_accessor.author_date(current_page.source_file)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
current_date.utc if current_date
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def repo_url
|
|
192
|
+
nested_dir, filename = parse_out_nested_dir_and_filename
|
|
193
|
+
|
|
194
|
+
repo_dir = match_repo_dir(nested_dir)
|
|
195
|
+
page_repo_config = config[:repo_links][repo_dir]
|
|
196
|
+
|
|
197
|
+
if page_repo_config && page_repo_config['ref']
|
|
198
|
+
org_repo = Pathname(page_repo_config['repo'])
|
|
199
|
+
ref = Pathname(page_repo_config['ref'])
|
|
200
|
+
at_path = at_path(page_repo_config)
|
|
201
|
+
nested_dir = extract_nested_directory(nested_dir, repo_dir)
|
|
202
|
+
|
|
203
|
+
"http://github.com/#{org_repo.join(Pathname('tree'), ref, Pathname(nested_dir), at_path, source_file(filename))}"
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def match_repo_dir(nested_dir)
|
|
208
|
+
config[:repo_links].keys
|
|
209
|
+
.select{ |key| nested_dir.match(/^#{key}/) }
|
|
210
|
+
.sort_by{ |key| key.length }
|
|
211
|
+
.last
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def source_file(filename)
|
|
215
|
+
fs = LocalFilesystemAccessor.new
|
|
216
|
+
|
|
217
|
+
if current_page.data.dita
|
|
218
|
+
source_filename = "#{filename}.xml"
|
|
219
|
+
|
|
220
|
+
if fs.source_file_exists?(Pathname(preprocessing_path(current_page.source_file)).dirname,
|
|
221
|
+
source_filename)
|
|
222
|
+
source_filename
|
|
223
|
+
else
|
|
224
|
+
''
|
|
225
|
+
end
|
|
226
|
+
else
|
|
227
|
+
"#{filename}.html.md.erb"
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def preprocessing_path(current_source_path)
|
|
232
|
+
root_path, nested_repo_path = current_source_path.split('source')
|
|
233
|
+
|
|
234
|
+
root_path.gsub!('/output/master_middleman', '')
|
|
235
|
+
|
|
236
|
+
"#{root_path}output/preprocessing/sections#{nested_repo_path}"
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def parse_out_nested_dir_and_filename
|
|
240
|
+
current_page.path
|
|
241
|
+
.match(/\/?(.*?)\/?([^\/]*)\.html$?/)
|
|
242
|
+
.captures
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def extract_nested_directory(nested_dir, repo_dir)
|
|
246
|
+
nested_dir = nested_dir.gsub("#{repo_dir}", '')
|
|
247
|
+
nested_dir = nested_dir.sub('/', '') if nested_dir[0] == '/'
|
|
248
|
+
|
|
249
|
+
nested_dir
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def at_path(page_repo_config)
|
|
253
|
+
path = page_repo_config['at_path'] || ""
|
|
254
|
+
|
|
255
|
+
Pathname(path)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def add_ancestors_of(page, ancestors)
|
|
259
|
+
if page
|
|
260
|
+
add_ancestors_of(page.parent, ancestors + [page])
|
|
261
|
+
else
|
|
262
|
+
ancestors
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def make_breadcrumb(page, is_current_page)
|
|
267
|
+
return nil unless (text = page.data.breadcrumb || page.data.title)
|
|
268
|
+
if is_current_page
|
|
269
|
+
css_class = 'active'
|
|
270
|
+
link = content_tag :span, text
|
|
271
|
+
else
|
|
272
|
+
link = link_to(text, '/' + page.path)
|
|
273
|
+
end
|
|
274
|
+
content_tag :li, link, :class => css_class
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
helpers HelperMethods
|
|
279
|
+
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
::Middleman::Extensions.register(:bookbinder, Bookbinder::Helpers)
|