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.
Files changed (129) hide show
  1. checksums.yaml +7 -0
  2. data/bookbinder.gemspec +46 -0
  3. data/install_bin/bookbinder +5 -0
  4. data/lib/bookbinder/cli.rb +105 -0
  5. data/lib/bookbinder/code_example_reader.rb +95 -0
  6. data/lib/bookbinder/colorizer.rb +16 -0
  7. data/lib/bookbinder/commands/bind.rb +120 -0
  8. data/lib/bookbinder/commands/collection.rb +181 -0
  9. data/lib/bookbinder/commands/components/bind/directory_preparer.rb +33 -0
  10. data/lib/bookbinder/commands/components/bind/layout_preparer.rb +27 -0
  11. data/lib/bookbinder/commands/components/command_options.rb +45 -0
  12. data/lib/bookbinder/commands/components/imprint/directory_preparer.rb +24 -0
  13. data/lib/bookbinder/commands/generate.rb +92 -0
  14. data/lib/bookbinder/commands/imprint.rb +55 -0
  15. data/lib/bookbinder/commands/punch.rb +33 -0
  16. data/lib/bookbinder/commands/update_local_doc_repos.rb +42 -0
  17. data/lib/bookbinder/commands/watch.rb +100 -0
  18. data/lib/bookbinder/config/checkers/archive_menu_checker.rb +29 -0
  19. data/lib/bookbinder/config/checkers/ditamap_presence_checker.rb +27 -0
  20. data/lib/bookbinder/config/checkers/duplicate_section_name_checker.rb +33 -0
  21. data/lib/bookbinder/config/checkers/products_checker.rb +34 -0
  22. data/lib/bookbinder/config/checkers/repository_name_presence_checker.rb +34 -0
  23. data/lib/bookbinder/config/checkers/required_keys_checker.rb +18 -0
  24. data/lib/bookbinder/config/checkers/section_presence_checker.rb +15 -0
  25. data/lib/bookbinder/config/configuration.rb +119 -0
  26. data/lib/bookbinder/config/configuration_decorator.rb +54 -0
  27. data/lib/bookbinder/config/dita_config_generator.rb +61 -0
  28. data/lib/bookbinder/config/fetcher.rb +64 -0
  29. data/lib/bookbinder/config/imprint/configuration.rb +24 -0
  30. data/lib/bookbinder/config/product_config.rb +34 -0
  31. data/lib/bookbinder/config/section_config.rb +85 -0
  32. data/lib/bookbinder/config/validator.rb +33 -0
  33. data/lib/bookbinder/config/yaml_loader.rb +34 -0
  34. data/lib/bookbinder/css_link_checker.rb +67 -0
  35. data/lib/bookbinder/directory_helpers.rb +15 -0
  36. data/lib/bookbinder/dita_command_creator.rb +95 -0
  37. data/lib/bookbinder/dita_html_for_middleman_formatter.rb +45 -0
  38. data/lib/bookbinder/errors/programmer_mistake.rb +5 -0
  39. data/lib/bookbinder/html_document_manipulator.rb +21 -0
  40. data/lib/bookbinder/ingest/cloner_factory.rb +26 -0
  41. data/lib/bookbinder/ingest/destination_directory.rb +21 -0
  42. data/lib/bookbinder/ingest/git_accessor.rb +102 -0
  43. data/lib/bookbinder/ingest/git_cloner.rb +36 -0
  44. data/lib/bookbinder/ingest/local_filesystem_cloner.rb +66 -0
  45. data/lib/bookbinder/ingest/missing_working_copy.rb +27 -0
  46. data/lib/bookbinder/ingest/repo_identifier.rb +45 -0
  47. data/lib/bookbinder/ingest/section_repository.rb +49 -0
  48. data/lib/bookbinder/ingest/update_failure.rb +15 -0
  49. data/lib/bookbinder/ingest/update_success.rb +12 -0
  50. data/lib/bookbinder/ingest/working_copy.rb +36 -0
  51. data/lib/bookbinder/local_filesystem_accessor.rb +122 -0
  52. data/lib/bookbinder/middleman_runner.rb +50 -0
  53. data/lib/bookbinder/postprocessing/link_checker.rb +125 -0
  54. data/lib/bookbinder/postprocessing/redirection.rb +38 -0
  55. data/lib/bookbinder/preprocessing/dita_html_preprocessor.rb +91 -0
  56. data/lib/bookbinder/preprocessing/dita_pdf_preprocessor.rb +48 -0
  57. data/lib/bookbinder/preprocessing/link_to_site_gen_dir.rb +39 -0
  58. data/lib/bookbinder/preprocessing/preprocessor.rb +26 -0
  59. data/lib/bookbinder/server_director.rb +30 -0
  60. data/lib/bookbinder/sheller.rb +52 -0
  61. data/lib/bookbinder/streams/colorized_stream.rb +25 -0
  62. data/lib/bookbinder/streams/filter_stream.rb +22 -0
  63. data/lib/bookbinder/subnav/navigation_entries_from_html_toc.rb +59 -0
  64. data/lib/bookbinder/subnav/navigation_entries_from_markdown_root.rb +116 -0
  65. data/lib/bookbinder/subnav/pdf_config_creator.rb +50 -0
  66. data/lib/bookbinder/subnav/subnav_generator.rb +28 -0
  67. data/lib/bookbinder/subnav/subnav_generator_factory.rb +29 -0
  68. data/lib/bookbinder/subnav/template_creator.rb +71 -0
  69. data/lib/bookbinder/terminal.rb +19 -0
  70. data/lib/bookbinder/values/output_locations.rb +91 -0
  71. data/lib/bookbinder/values/product_info.rb +11 -0
  72. data/lib/bookbinder/values/section.rb +58 -0
  73. data/lib/bookbinder/values/subnav_template.rb +4 -0
  74. data/lib/bookbinder/values/user_message.rb +15 -0
  75. data/master_middleman/archive_drop_down_menu.rb +50 -0
  76. data/master_middleman/bookbinder_helpers.rb +282 -0
  77. data/master_middleman/compass_runner.rb +0 -0
  78. data/master_middleman/config.rb +45 -0
  79. data/master_middleman/proof.rb +90 -0
  80. data/master_middleman/quicklinks_renderer.rb +80 -0
  81. data/master_middleman/source/javascripts/all.js +2 -0
  82. data/master_middleman/source/javascripts/book.js +1 -0
  83. data/master_middleman/source/javascripts/bookbinder.js +130 -0
  84. data/master_middleman/source/layouts/_additional-scripts.erb +0 -0
  85. data/master_middleman/source/layouts/_book-footer.erb +0 -0
  86. data/master_middleman/source/layouts/_book-search.erb +0 -0
  87. data/master_middleman/source/layouts/_book-title.erb +3 -0
  88. data/master_middleman/source/layouts/_header.erb +34 -0
  89. data/master_middleman/source/layouts/_local-header.erb +0 -0
  90. data/master_middleman/source/layouts/_page-footer.erb +1 -0
  91. data/master_middleman/source/layouts/_title.erb +5 -0
  92. data/master_middleman/source/layouts/layout.erb +70 -0
  93. data/master_middleman/source/stylesheets/all.css.scss +3 -0
  94. data/master_middleman/source/stylesheets/base.scss +324 -0
  95. data/master_middleman/source/stylesheets/book-styles.scss +0 -0
  96. data/master_middleman/source/stylesheets/layout-styles.scss +0 -0
  97. data/master_middleman/source/stylesheets/partials/_book-base-values.scss +0 -0
  98. data/master_middleman/source/stylesheets/partials/_book-vars.scss +0 -0
  99. data/master_middleman/source/stylesheets/partials/_default.scss +302 -0
  100. data/master_middleman/source/stylesheets/partials/_footer.scss +64 -0
  101. data/master_middleman/source/stylesheets/partials/_header.scss +419 -0
  102. data/master_middleman/source/stylesheets/partials/_layout-vars.scss +0 -0
  103. data/master_middleman/source/stylesheets/partials/_mixins.scss +53 -0
  104. data/master_middleman/source/stylesheets/partials/_reset.scss +233 -0
  105. data/master_middleman/source/stylesheets/partials/_search.scss +78 -0
  106. data/master_middleman/source/stylesheets/partials/_sidenav.scss +191 -0
  107. data/master_middleman/source/stylesheets/partials/_syntax-highlight.scss +64 -0
  108. data/master_middleman/source/stylesheets/partials/_vars.scss +64 -0
  109. data/master_middleman/source/stylesheets/print-book-styles.scss +0 -0
  110. data/master_middleman/source/stylesheets/print-layout-styles.scss +0 -0
  111. data/master_middleman/source/stylesheets/print.css.scss +57 -0
  112. data/master_middleman/source/subnavs/_default.erb +0 -0
  113. data/master_middleman/source/subnavs/_nav-links.erb +10 -0
  114. data/master_middleman/source/subnavs/_subnav_template.erb +8 -0
  115. data/master_middleman/subdirectory_aware_assets.rb +36 -0
  116. data/template_app/Gemfile +10 -0
  117. data/template_app/Gemfile.lock +49 -0
  118. data/template_app/config.ru +9 -0
  119. data/template_app/lib/rack_static_if_exists.rb +19 -0
  120. data/template_app/lib/search/handler.rb +73 -0
  121. data/template_app/lib/search/hit.rb +21 -0
  122. data/template_app/lib/search/query.rb +74 -0
  123. data/template_app/lib/search/renderer.rb +30 -0
  124. data/template_app/lib/server.rb +52 -0
  125. data/template_app/mail_sender.rb +61 -0
  126. data/template_app/rack_app.rb +110 -0
  127. data/template_app/search-results.html.erb +81 -0
  128. data/template_app/search.yml +23 -0
  129. 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,11 @@
1
+ module Bookbinder
2
+ ProductInfo = Struct.new(
3
+ :use_local_header,
4
+ :latest_stable_version,
5
+ :changelog_href,
6
+ :local_header_img,
7
+ :local_header_title
8
+ ) do
9
+
10
+ end
11
+ 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,4 @@
1
+ module Bookbinder
2
+ SubnavTemplate = Struct.new(:json_links,
3
+ :text)
4
+ 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)