bookwatch 1.0.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.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/bookwatch.gemspec +40 -0
  3. data/install_bin/bookwatch +5 -0
  4. data/lib/bookwatch/cli.rb +109 -0
  5. data/lib/bookwatch/code_example_reader.rb +95 -0
  6. data/lib/bookwatch/colorizer.rb +16 -0
  7. data/lib/bookwatch/commands/bind.rb +119 -0
  8. data/lib/bookwatch/commands/collection.rb +181 -0
  9. data/lib/bookwatch/commands/components/bind/directory_preparer.rb +33 -0
  10. data/lib/bookwatch/commands/components/bind/layout_preparer.rb +27 -0
  11. data/lib/bookwatch/commands/components/command_options.rb +45 -0
  12. data/lib/bookwatch/commands/components/imprint/directory_preparer.rb +24 -0
  13. data/lib/bookwatch/commands/generate.rb +92 -0
  14. data/lib/bookwatch/commands/imprint.rb +55 -0
  15. data/lib/bookwatch/commands/punch.rb +33 -0
  16. data/lib/bookwatch/commands/update_local_doc_repos.rb +42 -0
  17. data/lib/bookwatch/commands/watch.rb +100 -0
  18. data/lib/bookwatch/config/checkers/archive_menu_checker.rb +29 -0
  19. data/lib/bookwatch/config/checkers/ditamap_presence_checker.rb +27 -0
  20. data/lib/bookwatch/config/checkers/duplicate_section_name_checker.rb +33 -0
  21. data/lib/bookwatch/config/checkers/products_checker.rb +34 -0
  22. data/lib/bookwatch/config/checkers/repository_name_presence_checker.rb +34 -0
  23. data/lib/bookwatch/config/checkers/required_keys_checker.rb +18 -0
  24. data/lib/bookwatch/config/checkers/section_presence_checker.rb +15 -0
  25. data/lib/bookwatch/config/configuration.rb +119 -0
  26. data/lib/bookwatch/config/configuration_decorator.rb +54 -0
  27. data/lib/bookwatch/config/dita_config_generator.rb +61 -0
  28. data/lib/bookwatch/config/fetcher.rb +64 -0
  29. data/lib/bookwatch/config/imprint/configuration.rb +24 -0
  30. data/lib/bookwatch/config/product_config.rb +34 -0
  31. data/lib/bookwatch/config/section_config.rb +85 -0
  32. data/lib/bookwatch/config/validator.rb +33 -0
  33. data/lib/bookwatch/config/yaml_loader.rb +34 -0
  34. data/lib/bookwatch/css_link_checker.rb +67 -0
  35. data/lib/bookwatch/directory_helpers.rb +15 -0
  36. data/lib/bookwatch/dita_command_creator.rb +95 -0
  37. data/lib/bookwatch/dita_html_for_middleman_formatter.rb +45 -0
  38. data/lib/bookwatch/errors/programmer_mistake.rb +5 -0
  39. data/lib/bookwatch/html_document_manipulator.rb +21 -0
  40. data/lib/bookwatch/ingest/cloner_factory.rb +26 -0
  41. data/lib/bookwatch/ingest/destination_directory.rb +21 -0
  42. data/lib/bookwatch/ingest/git_accessor.rb +102 -0
  43. data/lib/bookwatch/ingest/git_cloner.rb +36 -0
  44. data/lib/bookwatch/ingest/local_filesystem_cloner.rb +66 -0
  45. data/lib/bookwatch/ingest/missing_working_copy.rb +27 -0
  46. data/lib/bookwatch/ingest/repo_identifier.rb +45 -0
  47. data/lib/bookwatch/ingest/section_repository.rb +49 -0
  48. data/lib/bookwatch/ingest/update_failure.rb +15 -0
  49. data/lib/bookwatch/ingest/update_success.rb +12 -0
  50. data/lib/bookwatch/ingest/working_copy.rb +36 -0
  51. data/lib/bookwatch/local_filesystem_accessor.rb +122 -0
  52. data/lib/bookwatch/middleman_runner.rb +48 -0
  53. data/lib/bookwatch/postprocessing/link_checker.rb +125 -0
  54. data/lib/bookwatch/postprocessing/redirection.rb +38 -0
  55. data/lib/bookwatch/preprocessing/dita_html_preprocessor.rb +91 -0
  56. data/lib/bookwatch/preprocessing/dita_pdf_preprocessor.rb +48 -0
  57. data/lib/bookwatch/preprocessing/link_to_site_gen_dir.rb +39 -0
  58. data/lib/bookwatch/preprocessing/preprocessor.rb +26 -0
  59. data/lib/bookwatch/server_director.rb +30 -0
  60. data/lib/bookwatch/sheller.rb +52 -0
  61. data/lib/bookwatch/streams/colorized_stream.rb +25 -0
  62. data/lib/bookwatch/streams/filter_stream.rb +22 -0
  63. data/lib/bookwatch/subnav/navigation_entries_from_html_toc.rb +59 -0
  64. data/lib/bookwatch/subnav/navigation_entries_from_markdown_root.rb +116 -0
  65. data/lib/bookwatch/subnav/pdf_config_creator.rb +50 -0
  66. data/lib/bookwatch/subnav/subnav_generator.rb +28 -0
  67. data/lib/bookwatch/subnav/subnav_generator_factory.rb +29 -0
  68. data/lib/bookwatch/subnav/template_creator.rb +71 -0
  69. data/lib/bookwatch/terminal.rb +19 -0
  70. data/lib/bookwatch/values/output_locations.rb +91 -0
  71. data/lib/bookwatch/values/product_info.rb +11 -0
  72. data/lib/bookwatch/values/section.rb +58 -0
  73. data/lib/bookwatch/values/subnav_template.rb +4 -0
  74. data/lib/bookwatch/values/user_message.rb +15 -0
  75. data/master_middleman/archive_drop_down_menu.rb +50 -0
  76. data/master_middleman/bookwatch_helpers.rb +259 -0
  77. data/master_middleman/compass_runner.rb +0 -0
  78. data/master_middleman/config.rb +34 -0
  79. data/master_middleman/quicklinks_renderer.rb +80 -0
  80. data/master_middleman/source/javascripts/all.js +2 -0
  81. data/master_middleman/source/javascripts/book.js +1 -0
  82. data/master_middleman/source/javascripts/bookwatch.js +103 -0
  83. data/master_middleman/source/layouts/_additional-scripts.erb +0 -0
  84. data/master_middleman/source/layouts/_book-footer.erb +0 -0
  85. data/master_middleman/source/layouts/_book-search.erb +0 -0
  86. data/master_middleman/source/layouts/_book-title.erb +3 -0
  87. data/master_middleman/source/layouts/_header.erb +34 -0
  88. data/master_middleman/source/layouts/_local-header.erb +0 -0
  89. data/master_middleman/source/layouts/_page-footer.erb +1 -0
  90. data/master_middleman/source/layouts/_title.erb +5 -0
  91. data/master_middleman/source/layouts/layout.erb +69 -0
  92. data/master_middleman/source/stylesheets/all.css.scss +3 -0
  93. data/master_middleman/source/stylesheets/base.scss +380 -0
  94. data/master_middleman/source/stylesheets/book-styles.css.scss +0 -0
  95. data/master_middleman/source/stylesheets/layout-styles.scss +0 -0
  96. data/master_middleman/source/stylesheets/partials/_book-base-values.scss +0 -0
  97. data/master_middleman/source/stylesheets/partials/_book-vars.scss +0 -0
  98. data/master_middleman/source/stylesheets/partials/_default.scss +300 -0
  99. data/master_middleman/source/stylesheets/partials/_footer.scss +64 -0
  100. data/master_middleman/source/stylesheets/partials/_header.scss +419 -0
  101. data/master_middleman/source/stylesheets/partials/_layout-vars.scss +0 -0
  102. data/master_middleman/source/stylesheets/partials/_mixins.scss +53 -0
  103. data/master_middleman/source/stylesheets/partials/_reset.scss +233 -0
  104. data/master_middleman/source/stylesheets/partials/_search.scss +78 -0
  105. data/master_middleman/source/stylesheets/partials/_sidenav.scss +191 -0
  106. data/master_middleman/source/stylesheets/partials/_syntax-highlight.scss +64 -0
  107. data/master_middleman/source/stylesheets/partials/_vars.scss +64 -0
  108. data/master_middleman/source/stylesheets/print.css.scss +58 -0
  109. data/master_middleman/source/subnavs/_default.erb +0 -0
  110. data/master_middleman/source/subnavs/_nav-links.erb +10 -0
  111. data/master_middleman/source/subnavs/_subnav_template.erb +8 -0
  112. data/master_middleman/subdirectory_aware_assets.rb +47 -0
  113. data/template_app/Gemfile +10 -0
  114. data/template_app/Gemfile.lock +43 -0
  115. data/template_app/config.ru +9 -0
  116. data/template_app/lib/rack_static_if_exists.rb +19 -0
  117. data/template_app/lib/search/handler.rb +47 -0
  118. data/template_app/lib/search/hit.rb +21 -0
  119. data/template_app/lib/search/query.rb +74 -0
  120. data/template_app/lib/search/renderer.rb +29 -0
  121. data/template_app/lib/server.rb +52 -0
  122. data/template_app/mail_sender.rb +69 -0
  123. data/template_app/rack_app.rb +110 -0
  124. data/template_app/search-results.html.erb +75 -0
  125. data/template_app/search.yml +22 -0
  126. metadata +491 -0
File without changes
@@ -0,0 +1,34 @@
1
+ require 'bookwatch_helpers'
2
+ require 'middleman-syntax'
3
+ require 'middleman-livereload'
4
+ require 'subdirectory_aware_assets'
5
+
6
+ config = YAML.load_file('bookwatch_config.yml')
7
+ config.each do |k, v|
8
+ set k, v
9
+ end
10
+
11
+ set :markdown_engine, :redcarpet
12
+ set :markdown, :layout_engine => :erb,
13
+ :tables => true,
14
+ :autolink => true,
15
+ :smartypants => true,
16
+ :fenced_code_blocks => true
17
+
18
+ set :css_dir, 'stylesheets'
19
+
20
+ set :js_dir, 'javascripts'
21
+
22
+ set :images_dir, 'images'
23
+
24
+ set :relative_links, false
25
+
26
+ page '/owners.json', :layout => false
27
+
28
+ activate :subdirectory_aware_assets
29
+
30
+ activate :navigation
31
+
32
+ activate :syntax
33
+
34
+ activate :livereload
@@ -0,0 +1,80 @@
1
+ require 'nokogiri'
2
+ require 'redcarpet'
3
+
4
+ class QuicklinksRenderer < Redcarpet::Render::Base
5
+ class BadHeadingLevelError < StandardError; end
6
+
7
+ attr_reader :vars
8
+
9
+ def initialize(template_variables)
10
+ super()
11
+ @vars = template_variables
12
+ end
13
+
14
+ def doc_header
15
+ @items = []
16
+ @items[1] = document.css('ul').first
17
+ nil
18
+ end
19
+
20
+ def doc_footer
21
+ document.css('.quick-links').to_html if any_headers?
22
+ end
23
+
24
+ def header(text, header_level)
25
+ return unless [2, 3].include?(header_level)
26
+ return unless anchor_for(text)
27
+
28
+ li = Nokogiri::XML::Node.new('li', document)
29
+ li.add_child anchor_for(text)
30
+ last_list_of_level(header_level-1).add_child(li)
31
+ @items[header_level] = li
32
+ nil
33
+ rescue BadHeadingLevelError => e
34
+ raise BadHeadingLevelError.new "The header \"#{text}\", which is at level #{e.message}, has no higher-level headers occurring before it."
35
+ end
36
+
37
+ private
38
+
39
+ def any_headers?
40
+ @items[2]
41
+ end
42
+
43
+ def anchor_for(text)
44
+ text = ERB.new(text).result(binding)
45
+ doc = Nokogiri::HTML(text)
46
+ target_anchor = doc.css('a').first
47
+ return unless target_anchor && target_anchor['id']
48
+ return if (target_anchor['class'] || '').match(/\bno-quick-link\b/)
49
+
50
+ anchor = Nokogiri::XML::Node.new('a', document)
51
+ anchor['href'] = "##{target_anchor['id']}"
52
+ anchor.content = doc.text.strip
53
+ anchor
54
+ end
55
+
56
+ def last_list_of_level(n)
57
+ item = @items[n]
58
+ raise BadHeadingLevelError.new("#{n+1}") unless item
59
+ return item if item.name == 'ul'
60
+
61
+ item.add_child('<ul>') unless item.css('ul').any?
62
+ @items[n] = item.css('ul').first
63
+ end
64
+
65
+ def document
66
+ builder.doc
67
+ end
68
+
69
+ def builder
70
+ @builder ||= Nokogiri::HTML::Builder.new(&base_quicklinks_doc)
71
+ end
72
+
73
+ def base_quicklinks_doc
74
+ Proc.new do |html|
75
+ html.div(class: 'quick-links') {
76
+ html.ul
77
+ }
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,2 @@
1
+ //= require bookwatch
2
+ //= require book
@@ -0,0 +1 @@
1
+ // Declare your book-specific javascript overrides in this file.
@@ -0,0 +1,103 @@
1
+ (function() {
2
+ var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
3
+
4
+ function toggleClass(el, className) {
5
+ var check = new RegExp("\\b" + className + "\\b");
6
+ if (check.test(el.className)) {
7
+ el.className = el.className.replace(check, '');
8
+ } else {
9
+ el.className += ' ' + className;
10
+ }
11
+ }
12
+
13
+ function openSubmenu(e) {
14
+ if (e.target.tagName !== 'A') {
15
+ var el = e.currentTarget;
16
+ toggleClass(el, 'expanded');
17
+ e.stopPropagation();
18
+ }
19
+ }
20
+
21
+ function registerOnClick(el, handler) {
22
+ if (el.addEventListener) {
23
+ el.addEventListener('click', handler);
24
+ } else {
25
+ el.onclick = handler;
26
+ }
27
+ }
28
+
29
+ function toggleMainMenu(e) {
30
+ var el = e.currentTarget;
31
+ toggleClass(el.parentNode, 'menu-active');
32
+ }
33
+
34
+ function toggleSubMenu(e) {
35
+ var el = e.currentTarget;
36
+ toggleClass(el.parentNode, 'active');
37
+ }
38
+
39
+ function displayDate(millis) {
40
+ millis = parseInt(millis, 10);
41
+ var date = new Date(millis);
42
+
43
+ return [MONTHS[date.getMonth()], ' ', date.getDate(), ', ', date.getFullYear()].join('');
44
+ }
45
+
46
+ window.Bookwatch = {
47
+ startSidenav: function(rootEl, currentPath) {
48
+ if (!rootEl) { return; }
49
+
50
+ var submenus = rootEl.querySelectorAll('.has_submenu');
51
+
52
+ for (var i = 0; i < submenus.length; i++) {
53
+ registerOnClick(submenus[i], openSubmenu);
54
+ }
55
+
56
+ if (currentPath) {
57
+ var currentLink = rootEl.querySelector('a[href="' + currentPath + '"]');
58
+ if (currentLink) {
59
+ currentLink.className += ' active';
60
+
61
+ var hasSubmenu = /\bhas_submenu\b/;
62
+ var subnavLocation = currentLink.parentNode;
63
+
64
+ while(subnavLocation.parentNode !== rootEl) {
65
+ subnavLocation = subnavLocation.parentNode;
66
+ if (hasSubmenu.test(subnavLocation.className)) {
67
+ subnavLocation.className += ' expanded';
68
+ }
69
+ }
70
+
71
+ rootEl.scrollTop = currentLink.offsetTop - rootEl.offsetTop;
72
+ }
73
+ }
74
+ },
75
+ mobileMainMenu: function(root) {
76
+ var mainMenus = root.querySelectorAll('[data-behavior=MenuMobile]');
77
+
78
+ for (var i = 0; i < mainMenus.length; i++) {
79
+ registerOnClick(mainMenus[i], toggleMainMenu);
80
+ }
81
+ },
82
+ mobileSubMenu: function(root) {
83
+ var subMenus = root.querySelectorAll('[data-behavior=SubMenuMobile]');
84
+
85
+ for (var i = 0; i < subMenus.length; i++) {
86
+ registerOnClick(subMenus[i], toggleSubMenu);
87
+ }
88
+ },
89
+ modifiedDates: function(root) {
90
+ var datesElements = root.querySelectorAll('[data-behavior=DisplayModifiedDate]');
91
+
92
+ for (var i = 0; i < datesElements.length; i++) {
93
+ datesElements[i].innerText = displayDate(datesElements[i].getAttribute('data-modified-date'));
94
+ }
95
+ },
96
+ boot: function() {
97
+ Bookwatch.startSidenav(document.querySelector('#sub-nav'), document.location.pathname);
98
+ Bookwatch.mobileMainMenu(document);
99
+ Bookwatch.mobileSubMenu(document);
100
+ Bookwatch.modifiedDates(document);
101
+ }
102
+ };
103
+ })();
@@ -0,0 +1,3 @@
1
+ <!--Default title-->
2
+ <!--If book needs something different, add a book-title partial to the book's layouts folder-->
3
+ <%= vars.title %>
@@ -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 %>
@@ -0,0 +1 @@
1
+ <%= render_repo_link %>
@@ -0,0 +1,5 @@
1
+ <% if current_page.data.title %>
2
+ <h1 class="title-container">
3
+ <%= current_page.data.title %>
4
+ </h1>
5
+ <% end %>
@@ -0,0 +1,69 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <!-- Always force latest IE rendering engine or request Chrome Frame -->
6
+ <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
7
+
8
+ <link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300italic,400italic,400,600' rel='stylesheet' type='text/css'>
9
+ <!-- Use title if it's in the page YAML frontmatter -->
10
+ <title>
11
+ <% if data.page.title %>
12
+ <%= data.page.title %> |
13
+ <% end %>
14
+ <%= vars.book_title_short %>
15
+ </title>
16
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
17
+ <%= stylesheet_link_tag 'all', :media => 'screen, print' %>
18
+ <%= stylesheet_link_tag 'print', :media => 'print' %>
19
+ <link href='/images/favicon.ico' rel='shortcut icon'>
20
+
21
+ <%= javascript_include_tag "all" %>
22
+ <%= partial 'layouts/additional-scripts' %>
23
+ </head>
24
+
25
+ <body class="<%= body_classes %><%= yield_for_subnav.empty? ? '' : ' has-subnav' %>">
26
+
27
+ <div class="viewport">
28
+ <div class='wrap'>
29
+ <script type="text/javascript">
30
+ document.domain = "<%= vars.domain_name %>";
31
+ </script>
32
+
33
+ <%= partial 'layouts/header' %>
34
+
35
+ <div class="container">
36
+
37
+ <!--googleoff: index-->
38
+ <%= yield_for_subnav %>
39
+ <!--googleon: index-->
40
+
41
+ <main class="content content-layout" id="js-content" role="main">
42
+ <a id="top"></a>
43
+ <%= partial 'layouts/local-header' %>
44
+ <%= partial 'layouts/title' %>
45
+ <% if quick_links %>
46
+ <div id="js-quick-links" <%= 'class="list-style-none"' if data.page.list_style_none %>>
47
+ <%= quick_links %>
48
+ </div>
49
+ <% end %>
50
+ <div class="to-top" id="js-to-top">
51
+ <a href="#top" title="back to top"></a>
52
+ </div>
53
+ <%= yield %>
54
+ <%= partial 'layouts/page-footer' %>
55
+ </main>
56
+ </div>
57
+ </div>
58
+ </div>
59
+
60
+ <div id="scrim"></div>
61
+
62
+ <div class="container">
63
+ <footer class="site-footer-links">
64
+ <%= partial 'layouts/book-footer' %>
65
+ </footer>
66
+ </div><!--end of container-->
67
+
68
+ </body>
69
+ </html>
@@ -0,0 +1,3 @@
1
+ @import "base";
2
+ @import "layout-styles";
3
+ @import "book-styles";
@@ -0,0 +1,380 @@
1
+ @import "font-awesome/variables";
2
+ @import "font-awesome/core";
3
+ @import "font-awesome/path";
4
+
5
+ @import "partials/vars";
6
+ @import "partials/mixins";
7
+
8
+ @import "partials/reset";
9
+ @import "partials/default";
10
+
11
+ @import "partials/syntax-highlight";
12
+ @import "partials/header";
13
+ @import "partials/footer";
14
+ @import "partials/search";
15
+ @import "partials/sidenav";
16
+
17
+
18
+ // ~LAYOUT
19
+ // ===================================================
20
+ .container {
21
+ background: #fff;
22
+ clear: both;
23
+ margin: 0 auto;
24
+ max-width: 1024px;
25
+ }
26
+ .content-layout {
27
+ padding: 2em 1.5em 2em 1.5em;
28
+ @media (min-width: $bp-wide) {
29
+ padding-top: 0;
30
+ }
31
+
32
+ @media (min-width: $bp-wide) {
33
+ #top:before {
34
+ content: '';
35
+ padding-bottom: 4em;
36
+ border: none;
37
+ display: block;
38
+ }
39
+ }
40
+ }
41
+ .has-subnav .container {
42
+ max-width: auto;
43
+ @media (min-width: $bp-wide) {
44
+ margin-left: $sidenav-wide;
45
+ }
46
+ @media (min-width: $bp-widest) {
47
+ margin-left: $sidenav-widest;
48
+ }
49
+ }
50
+ .has-subnav .content-layout {
51
+ @media (min-width: $bp-wide) {
52
+ max-width: 45em;
53
+ padding: 0 2em 2em;
54
+ }
55
+ }
56
+ .nav-container {
57
+ @media (min-width: $bp-wide) {
58
+ position: fixed;
59
+ z-index: 10;
60
+ top: 38px;
61
+ left: 0;
62
+ bottom: 0;
63
+ overflow-y: auto;
64
+ overflow-x: hidden;
65
+ -webkit-overflow-scrolling: touch;
66
+ width: $sidenav-wide;
67
+ }
68
+ @media (min-width: $bp-widest) {
69
+ width: $sidenav-widest;
70
+ }
71
+ }
72
+
73
+
74
+ // ~SIDE NAV RELATED STYLES
75
+ // ===================================================
76
+ .has-sidenav table {
77
+ border-color: $color-border;
78
+ border: 1px solid $color-border;
79
+ }
80
+ .has-sidenav th {
81
+ background-color: transparentize($color-accent, 0.95);
82
+ }
83
+ .has-sidenav table tr:nth-child(2n+1) {
84
+ background: none;
85
+ }
86
+ .has-sidenav .content tr:nth-child(2n+1) {
87
+ background-color: $color-border-row;
88
+ }
89
+
90
+ // ~GRID HELPER
91
+ // ===================================================
92
+ .span3 {
93
+ display: block;
94
+ @media (min-width: $bp-wide) {
95
+ // 2 col
96
+ float: left;
97
+ margin-right: 2%;
98
+ width: 48%;
99
+ }
100
+ @media (min-width: $bp-widest) {
101
+ // 3 col
102
+ width: 32%;
103
+ }
104
+ }
105
+ // first of 2
106
+ .span3:nth-child(2n+1) {
107
+ @media (min-width: $bp-wide) and (max-width: $bp-widest) {
108
+ clear: left;
109
+ }
110
+ }
111
+ // last of 2
112
+ .span3:nth-child(2n) {
113
+ @media (min-width: $bp-wide) and (max-width: $bp-widest) {
114
+ margin-right: 0;
115
+ }
116
+ }
117
+
118
+ // first of 3
119
+ .span3:nth-child(3n+1) {
120
+ @media (min-width: $bp-widest) {
121
+ clear: left;
122
+ }
123
+ }
124
+ // last of 3
125
+ .span3:nth-child(3n) {
126
+ @media (min-width: $bp-widest) {
127
+ margin-right: 0;
128
+ }
129
+ }
130
+
131
+ /*doc
132
+ ---
133
+ title: Title Container
134
+ name: title_container
135
+ category: basics
136
+ ---
137
+ ```html_example
138
+ <h1 class="title-container">
139
+ Lorem Ipsum Dolor
140
+ </h1>
141
+ ```
142
+ */
143
+
144
+ // Title of content
145
+ .title-container {
146
+ line-height: 1.1;
147
+ font-weight: 600;
148
+ font-size: $font-size-xl;
149
+ margin-top: 0;
150
+ @media (min-width: $bp-wide) {
151
+ font-size: $font-size-xxl
152
+ }
153
+ }
154
+
155
+ // ~QUICK LINKS
156
+ // ===================================================
157
+ /*doc
158
+ ---
159
+ title: Nav - Quick Links
160
+ name: nav-quick_links
161
+ category: basics
162
+ ---
163
+ ```html_example
164
+ <div class="quick-links">
165
+ <ul>
166
+ <li><a href="#">quick link</a></li>
167
+ <li><a href="#">quick link</a></li>
168
+ <li><a href="#">quick link</a></li>
169
+ </ul>
170
+ </div>
171
+ ```
172
+ */
173
+ .quick-links {
174
+ background-color: $color-bg-light;
175
+ border-radius: 3px;
176
+ border: 1px solid $color-border-superlight;
177
+ display: inline-block;
178
+ padding: 1em 1.5em;
179
+
180
+ ol, ul, li {
181
+ margin: 0;
182
+ }
183
+
184
+ > ul {
185
+ list-style-position: inside;
186
+ list-style-type: lower-roman;
187
+ margin-left: -1em;
188
+
189
+ &:before {
190
+ content: "In this topic:";
191
+ display: block;
192
+ padding-bottom: 0.25em;
193
+ }
194
+ }
195
+
196
+ ul ul {
197
+ padding-left: 1.8em;
198
+ }
199
+ }
200
+
201
+ .list-style-none .quick-links > ul {
202
+ list-style-type: none;
203
+ }
204
+
205
+ // ~CONTENT
206
+ // ===================================================
207
+ // Designate external links with an icon
208
+
209
+ /*doc
210
+ ---
211
+ title: Link External
212
+ name: link_external
213
+ category: basics
214
+ ---
215
+ ```html_example
216
+ <a class="external-link" href="#">Link</a>
217
+ ```
218
+ */
219
+ .content a[href^="http"]:after,
220
+ .external-link:after {
221
+ @extend .fa;
222
+ content: $fa-var-external-link;
223
+ font-size: 0.75em;
224
+ padding-left: 0.5em;
225
+ }
226
+
227
+ .content a:hover,
228
+ .content a:focus,
229
+ .content a:active,
230
+ .link:hover,
231
+ .link:focus,
232
+ .link:active {
233
+ background-color: transparentize($color-accent-bright, 0.92);
234
+ border-bottom-style: solid;
235
+ }
236
+
237
+ // Enlarge first paragraph of content.
238
+
239
+ /*doc
240
+ ---
241
+ title: Content Helper - Intro
242
+ name: content_helper-intro
243
+ category: basics
244
+ ---
245
+ ```html_example
246
+ <p class="intro">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Necessitatibus totam libero facilis voluptatem aliquam incidunt ipsa officiis, dicta nihil expedita, molestiae delectus impedit hic quidem deserunt laudantium, sint debitis tenetur.</p>
247
+ ```
248
+ */
249
+
250
+ .intro {
251
+ font-size: $font-size-m;
252
+ font-weight: 300;
253
+ }
254
+
255
+ /*doc
256
+ ---
257
+ title: Content Helper - Note
258
+ name: content_helper-note
259
+ category: basics
260
+ ---
261
+ ```html_example
262
+ <p class="note">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Necessitatibus totam libero facilis voluptatem aliquam incidunt ipsa officiis, dicta nihil expedita, molestiae delectus impedit hic quidem deserunt laudantium, sint debitis tenetur.</p>
263
+ ```
264
+ */
265
+
266
+ // Notes and tips
267
+ .note {
268
+ background: #ffffed;
269
+ border-color: #ebebd3;
270
+ border-radius: 3px;
271
+ border-style: solid;
272
+ border-width: 1px;
273
+ margin: 1em 0;
274
+ padding: 0.7em 1em 0.7em 2.3em;
275
+ position: relative;
276
+ &:before {
277
+ content: $fa-var-lightbulb-o;
278
+ @extend .fa;
279
+ color: #b9b781;
280
+ font-size: 1.5em;
281
+ left: 0.6em;
282
+ position: absolute;
283
+ top: 0.45em;
284
+ }
285
+ }
286
+
287
+ /*doc
288
+ ---
289
+ title: Content Helper - New User Tip
290
+ name: content_helper-tip
291
+ category: basics
292
+ ---
293
+ ```html_example
294
+ <p class="tip">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Necessitatibus totam libero facilis voluptatem aliquam incidunt ipsa officiis, dicta nihil expedita, molestiae delectus impedit hic quidem deserunt laudantium, sint debitis tenetur.</p>
295
+ ```
296
+ */
297
+
298
+ // Tips for first-time users
299
+ .tip {
300
+ background: #ffffff;
301
+ border-color: $color-border-tip;
302
+ border-radius: 3px;
303
+ border-style: solid;
304
+ border-width: 1px;
305
+ margin: 1em 0;
306
+ padding: 1.7em 2em;
307
+ position: relative;
308
+ text-align: left;
309
+ &:before {
310
+ @extend .fa;
311
+ color: #7C7C7C;
312
+ font-size: $font-size-xl;
313
+ left: 0.5em;
314
+ position: absolute;
315
+ top: 0.8em;
316
+ }
317
+ }
318
+
319
+ // ~CODE EXAMPLE STYLES
320
+ // ===================================================
321
+
322
+ /*doc
323
+ ---
324
+ title: Code Example - Terminal
325
+ name: code_example-terminal
326
+ category: basics
327
+ ---
328
+ ```html_example
329
+ <pre class="terminal">$ keytool -import -alias ops-metrics-ssl -file ops-metrics.cer -keystore localhost.truststore</pre>
330
+ ```
331
+ */
332
+
333
+ .terminal {
334
+ background-color: #3a3a3a;
335
+ border: 0;
336
+ color: #fefefe;
337
+ }
338
+
339
+
340
+ // ~BACK TO TOP
341
+ // ===================================================
342
+ .to-top {
343
+ visibility: hidden;
344
+ opacity: 0;
345
+ @include transition(all 0.2s linear);
346
+ a {
347
+ border: 0;
348
+ bottom: 4em;
349
+ position: fixed;
350
+ right: 4em;
351
+ z-index: 10;
352
+ &:hover {
353
+ background: none;
354
+ }
355
+ &:before {
356
+ content: $fa-var-arrow-up;
357
+ @extend .fa;
358
+ background: $color-accent-bright;
359
+ box-shadow: 0 0 9px rgba(153, 153, 153, 0.8);
360
+ color: #fff;
361
+ line-height: 2.5em;
362
+ height: 2.5em;
363
+ text-align: center;
364
+ width: 2.5em;
365
+ }
366
+ }
367
+ &.sticky {
368
+ // display: inline-block;
369
+ visibility: visible;
370
+ opacity: 1;
371
+ }
372
+ @media (max-width: $bp-wide) {
373
+ // Hide back to top on narrow width screens
374
+ display: none;
375
+ }
376
+ }
377
+ // Hide back to top on homepage
378
+ .index .to-top {
379
+ display: none;
380
+ }