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,39 @@
1
+ require_relative '../subnav/subnav_generator'
2
+ require_relative '../subnav/navigation_entries_from_markdown_root'
3
+
4
+ module Bookbinder
5
+ module Preprocessing
6
+ class LinkToSiteGenDir
7
+ def initialize(filesystem, subnav_generator_factory)
8
+ @filesystem = filesystem
9
+ @subnav_generator_factory = subnav_generator_factory
10
+ end
11
+
12
+ def applicable_to?(section)
13
+ filesystem.file_exist?(section.path_to_repo_dir)
14
+ end
15
+
16
+ def preprocess(sections, output_locations, config: nil, options: {}, **_)
17
+ sections.each do |section|
18
+ filesystem.link_creating_intermediate_dirs(
19
+ section.path_to_repo_dir,
20
+ output_locations.source_for_site_generator.join(section.destination_directory)
21
+ )
22
+ end
23
+
24
+ generator = subnav_generator(options[:require_valid_subnav_links])
25
+ config.products.each do |product|
26
+ generator.generate(product)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def subnav_generator(require_valid_subnav_links)
33
+ @subnav_generator ||= subnav_generator_factory.produce(Subnav::NavigationEntriesFromMarkdownRoot.new(filesystem, require_valid_subnav_links))
34
+ end
35
+
36
+ attr_reader :filesystem, :subnav_generator_factory
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,26 @@
1
+ module Bookbinder
2
+ module Preprocessing
3
+ class Preprocessor
4
+ class NullProcess
5
+ def preprocess(*)
6
+ end
7
+ end
8
+
9
+ def initialize(*processes)
10
+ @processes = processes
11
+ end
12
+
13
+ def preprocess(sections, *args)
14
+ sections.group_by { |section|
15
+ processes.detect(Proc.new { NullProcess.new }) { |process| process.applicable_to?(section) }
16
+ }.each do |process, grouped_sections|
17
+ process.preprocess(grouped_sections, *args)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :processes
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ require 'puma'
2
+
3
+ module Bookbinder
4
+ class ServerDirector
5
+ def initialize(app: nil, directory: nil, port: 41722)
6
+ @app = app
7
+ @directory = directory
8
+ @port = port
9
+ end
10
+
11
+ def use_server
12
+ Dir.chdir(@directory) do
13
+ events = Puma::Events.new $stdout, $stderr
14
+ server = Puma::Server.new app, events
15
+ server.add_tcp_listener "localhost", @port
16
+ server.run
17
+ begin
18
+ result = yield @port
19
+ ensure
20
+ server.stop(true)
21
+ end
22
+ result
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :app
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ require 'open3'
2
+
3
+ module Bookbinder
4
+ class Sheller
5
+ ShelloutFailure = Class.new(RuntimeError)
6
+
7
+ class DevNull
8
+ def puts(_)
9
+ end
10
+
11
+ def <<(_)
12
+ end
13
+ end
14
+
15
+ def run_command(*command)
16
+ out, err =
17
+ if Hash === command.last
18
+ command.last.values_at(:out, :err)
19
+ else
20
+ [DevNull.new, DevNull.new]
21
+ end
22
+
23
+ env_vars, executable =
24
+ if Hash === command.first
25
+ command[0..1]
26
+ else
27
+ [{}, command[0]]
28
+ end
29
+
30
+ exit_status = nil
31
+ Open3.popen3(env_vars, executable) do |stdin, stdout, stderr, wait_thr|
32
+ t = Thread.new do
33
+ stdout.each do |line|
34
+ out.puts(line)
35
+ end
36
+ end
37
+ stderr.each do |line|
38
+ err.puts(line)
39
+ end
40
+ t.join
41
+ exit_status = wait_thr.value
42
+ end
43
+ exit_status
44
+ end
45
+
46
+ def get_stdout(command)
47
+ out = StringIO.new
48
+ run_command(command, out: out)
49
+ out.tap(&:rewind).read.chomp
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../colorizer'
2
+
3
+ module Bookbinder
4
+ module Streams
5
+ class ColorizedStream
6
+ def initialize(color, stream)
7
+ @color = color
8
+ @stream = stream
9
+ @colorizer = Colorizer.new
10
+ end
11
+
12
+ def puts(line)
13
+ stream.puts(colorizer.colorize(line, color))
14
+ end
15
+
16
+ def <<(text)
17
+ stream << colorizer.colorize(text, color)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :color, :colorizer, :stream
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ module Bookbinder
2
+ module Streams
3
+ class FilterStream
4
+ def initialize(matcher_regex, stream)
5
+ @matcher_regex = matcher_regex
6
+ @stream = stream
7
+ end
8
+
9
+ def puts(line)
10
+ stream.puts(line.gsub("\n", '')) if line.match(matcher_regex)
11
+ end
12
+
13
+ def <<(line)
14
+ stream << line.gsub("\n", '') if line.match(matcher_regex)
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :matcher_regex, :stream
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,59 @@
1
+ require 'nokogiri'
2
+ require 'active_support/all'
3
+
4
+ module Bookbinder
5
+ module Subnav
6
+ class NavigationEntriesFromHtmlToc
7
+ def initialize(fs)
8
+ @fs = fs
9
+ @external_link_check = %r{\Ahttps?://}
10
+ end
11
+
12
+ def get_links(section, output_locations)
13
+ @section, @output_locations = section, output_locations
14
+
15
+ doc = parse_toc_file
16
+ set_anchor_values(doc.css('a'))
17
+
18
+ gather_urls_and_texts(doc.css('body > ul'))
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :fs, :section, :output_locations
24
+
25
+ def parse_toc_file
26
+ html = fs.read(
27
+ File.join(
28
+ output_locations.html_from_preprocessing_dir,
29
+ section.destination_directory,
30
+ 'index.html')
31
+ )
32
+ Nokogiri::XML(html)
33
+ end
34
+
35
+ def set_anchor_values(anchors)
36
+ anchors.each do |anchor|
37
+ unless @external_link_check.match(anchor['href'])
38
+ anchor['href'] = "/#{section.destination_directory}/#{anchor['href']}"
39
+ end
40
+ end
41
+ end
42
+
43
+ def gather_urls_and_texts(base_node)
44
+ top_level_li = base_node.css("> li")
45
+ top_level_li.map do |li|
46
+ anchor = li.css('a')[0]
47
+ href = anchor['href']
48
+ text = anchor.inner_text
49
+ ul = li.css('> ul')
50
+ if ul.size > 0
51
+ {url: href, text: text, nested_links: gather_urls_and_texts(ul)}
52
+ else
53
+ {url: href, text: text}
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,116 @@
1
+ require 'json'
2
+ require 'nokogiri'
3
+ require 'redcarpet'
4
+
5
+ module Bookbinder
6
+ module Subnav
7
+ class NavigationEntriesFromMarkdownRoot
8
+ SubnavDuplicateLinkError = Class.new(RuntimeError)
9
+ SubnavBrokenLinkError = Class.new(RuntimeError)
10
+ SubnavRootMissingError = Class.new(RuntimeError)
11
+
12
+ def initialize(fs, require_valid_subnav_links)
13
+ @fs = fs
14
+ @require_valid_subnav_links = require_valid_subnav_links
15
+ @renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new)
16
+ end
17
+
18
+ def get_links(product_config, output_locations)
19
+ @source_for_site_gen = output_locations.source_for_site_generator
20
+ @config = product_config
21
+
22
+ root = absolute_source_from_path(Pathname(config.subnav_root))
23
+
24
+ if root.nil?
25
+ if @require_valid_subnav_links
26
+ raise SubnavRootMissingError.new('Subnav root not found at: ' + config.subnav_root)
27
+ else
28
+ return []
29
+ end
30
+ end
31
+
32
+ @parsed_files = {Pathname(root) => '(root)'}
33
+
34
+ gather_urls_and_texts(root)
35
+ end
36
+
37
+ attr_reader :fs, :source_for_site_gen, :renderer, :config
38
+
39
+ private
40
+
41
+ def get_html(md)
42
+ Nokogiri::HTML(renderer.render(md))
43
+ end
44
+
45
+ def absolute_source_from_path(path)
46
+ full_sources = fs.find_files_extension_agnostically(path, source_for_site_gen)
47
+ full_sources.first
48
+ end
49
+
50
+ # href: ./cat/index.html
51
+ # expanded href: my/cat/index.html
52
+ # full source: my/cat/index.html.md.erb
53
+ def gather_urls_and_texts(source)
54
+ toc_md = fs.read(source)
55
+ base_node = get_html(toc_md).css('html')
56
+
57
+ nav_items(base_node).map do |element|
58
+ href = element['href']
59
+ expanded_href = (source.dirname + href).relative_path_from(source_for_site_gen)
60
+ next_source = absolute_source_from_path(expanded_href)
61
+ nested_links = {}
62
+
63
+ no_children = false
64
+ no_children ||= validate_no_broken_link(expanded_href, next_source, source)
65
+ no_children ||= validate_no_duplicate_link(expanded_href, next_source, source)
66
+
67
+ unless no_children
68
+ @parsed_files[next_source] = source
69
+ nested_urls_and_texts = gather_urls_and_texts(next_source)
70
+ nested_links.merge!(nested_links: nested_urls_and_texts) unless nested_urls_and_texts.empty?
71
+ end
72
+
73
+ {url: '/' + expanded_href.to_s, text: element.inner_text}.merge(nested_links)
74
+ end
75
+ end
76
+
77
+ def validate_no_duplicate_link(expanded_href, next_source, source)
78
+ if @parsed_files.has_key?(next_source)
79
+ if @require_valid_subnav_links
80
+ raise SubnavDuplicateLinkError.new(<<-ERROR)
81
+ )
82
+ Duplicate link found in subnav for product_id: #{config.id}
83
+
84
+ Link: #{expanded_href}
85
+ Original file: #{@parsed_files[next_source]}
86
+ Current file: #{source}
87
+ ERROR
88
+ else
89
+ no_children = true
90
+ end
91
+ end
92
+ no_children
93
+ end
94
+
95
+ def validate_no_broken_link(expanded_href, next_source, source)
96
+ unless next_source
97
+ if @require_valid_subnav_links
98
+ raise SubnavBrokenLinkError.new(<<-ERROR)
99
+ Broken link found in subnav for product_id: #{config.id}
100
+
101
+ Link: #{expanded_href}
102
+ Source file: #{source}
103
+ ERROR
104
+ else
105
+ no_children = true
106
+ end
107
+ end
108
+ no_children
109
+ end
110
+
111
+ def nav_items(base_node)
112
+ base_node.css('a.subnav')
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,50 @@
1
+ require 'yaml'
2
+
3
+ module Bookbinder
4
+ module Subnav
5
+ class PdfConfigCreator
6
+ def initialize(fs, output_locations)
7
+ @fs = fs
8
+ @output_locations = output_locations
9
+ end
10
+
11
+ def create(navigation_entries, subnav_config)
12
+ @links = format_links(navigation_entries)
13
+
14
+ fs.overwrite(to: output_locations.pdf_config_dir.join(subnav_config.pdf_config),
15
+ text: config_content)
16
+ end
17
+
18
+ attr_reader :fs, :output_locations
19
+
20
+ private
21
+
22
+ def props_location(filename)
23
+ output_locations.subnavs_for_layout_dir.join(filename)
24
+ end
25
+
26
+ def format_links(links)
27
+ links.map{|item| item[:url] }.compact.map{|link| link.sub(/^\//, '')}
28
+ end
29
+
30
+ def config_content
31
+ config_keys.inject({}) do |hash, key|
32
+ hash[key] = content_for(key)
33
+ hash
34
+ end.to_yaml
35
+ end
36
+
37
+ def config_keys
38
+ %w{copyright_notice header executable pages}
39
+ end
40
+
41
+ def content_for(key)
42
+ key == 'pages' ? @links : default_content
43
+ end
44
+
45
+ def default_content
46
+ 'REPLACE ME'
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,28 @@
1
+ module Bookbinder
2
+ module Subnav
3
+ class SubnavGenerator
4
+ def initialize(navigation_entries_parser, template_creator, pdf_config_creator, output_locations)
5
+ @navigation_entries_parser = navigation_entries_parser
6
+ @template_creator = template_creator
7
+ @pdf_config_creator = pdf_config_creator
8
+ @output_locations = output_locations
9
+ end
10
+
11
+ def generate(subnav_spec)
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)
15
+ end
16
+
17
+ attr_reader :navigation_entries_parser, :template_creator, :pdf_config_creator
18
+
19
+ private
20
+
21
+ attr_reader :output_locations
22
+
23
+ def pdf?(subnav_spec)
24
+ subnav_spec.respond_to?(:pdf_config) && subnav_spec.pdf_config
25
+ end
26
+ end
27
+ end
28
+ end