docyard 0.9.0 → 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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -0
  3. data/README.md +8 -253
  4. data/exe/docyard +6 -0
  5. data/lib/docyard/build/asset_bundler.rb +2 -2
  6. data/lib/docyard/build/file_copier.rb +12 -5
  7. data/lib/docyard/build/llms_txt_generator.rb +103 -0
  8. data/lib/docyard/build/sitemap_generator.rb +1 -1
  9. data/lib/docyard/build/static_generator.rb +115 -79
  10. data/lib/docyard/builder.rb +6 -2
  11. data/lib/docyard/cli.rb +14 -4
  12. data/lib/docyard/components/processors/callout_processor.rb +1 -1
  13. data/lib/docyard/components/processors/code_block_extended_fence_postprocessor.rb +24 -0
  14. data/lib/docyard/components/processors/code_block_extended_fence_preprocessor.rb +44 -0
  15. data/lib/docyard/components/processors/code_block_options_preprocessor.rb +11 -1
  16. data/lib/docyard/components/processors/code_block_processor.rb +5 -24
  17. data/lib/docyard/components/processors/code_group_processor.rb +6 -22
  18. data/lib/docyard/components/processors/code_snippet_import_preprocessor.rb +1 -0
  19. data/lib/docyard/components/processors/file_tree_processor.rb +1 -2
  20. data/lib/docyard/components/processors/icon_processor.rb +8 -2
  21. data/lib/docyard/components/processors/include_processor.rb +10 -10
  22. data/lib/docyard/components/processors/video_embed_processor.rb +14 -3
  23. data/lib/docyard/components/support/code_block/feature_extractor.rb +3 -1
  24. data/lib/docyard/components/support/code_block/icon_detector.rb +5 -12
  25. data/lib/docyard/components/support/code_block/line_number_resolver.rb +30 -0
  26. data/lib/docyard/components/support/code_detector.rb +2 -12
  27. data/lib/docyard/components/support/code_group/html_builder.rb +2 -6
  28. data/lib/docyard/components/support/tabs/icon_detector.rb +6 -2
  29. data/lib/docyard/components/support/tabs/parser.rb +6 -23
  30. data/lib/docyard/config/analytics_resolver.rb +24 -0
  31. data/lib/docyard/config/branding_resolver.rb +58 -27
  32. data/lib/docyard/config/key_validator.rb +30 -0
  33. data/lib/docyard/config/logo_detector.rb +8 -8
  34. data/lib/docyard/config/schema.rb +39 -0
  35. data/lib/docyard/config/section.rb +21 -0
  36. data/lib/docyard/config/validation_helpers.rb +83 -0
  37. data/lib/docyard/config/validator.rb +45 -144
  38. data/lib/docyard/config/validators/navigation.rb +43 -0
  39. data/lib/docyard/config/validators/section.rb +114 -0
  40. data/lib/docyard/config.rb +46 -102
  41. data/lib/docyard/constants.rb +59 -0
  42. data/lib/docyard/{utils/errors.rb → errors.rb} +6 -0
  43. data/lib/docyard/initializer.rb +100 -49
  44. data/lib/docyard/navigation/page_navigation_builder.rb +65 -0
  45. data/lib/docyard/navigation/sidebar/auto_builder.rb +107 -0
  46. data/lib/docyard/navigation/sidebar/cache.rb +96 -0
  47. data/lib/docyard/navigation/sidebar/config_builder.rb +179 -0
  48. data/lib/docyard/navigation/sidebar/distributed_builder.rb +145 -0
  49. data/lib/docyard/navigation/sidebar/local_config_loader.rb +69 -3
  50. data/lib/docyard/navigation/sidebar/renderer.rb +12 -1
  51. data/lib/docyard/navigation/sidebar_builder.rb +43 -81
  52. data/lib/docyard/rendering/branding_variables.rb +65 -0
  53. data/lib/docyard/rendering/icon_helpers.rb +14 -1
  54. data/lib/docyard/rendering/icons/devicons.rb +63 -0
  55. data/lib/docyard/rendering/icons.rb +26 -27
  56. data/lib/docyard/rendering/markdown.rb +5 -23
  57. data/lib/docyard/rendering/og_helpers.rb +36 -0
  58. data/lib/docyard/rendering/renderer.rb +87 -59
  59. data/lib/docyard/rendering/template_resolver.rb +14 -0
  60. data/lib/docyard/routing/fallback_resolver.rb +3 -3
  61. data/lib/docyard/search/build_indexer.rb +2 -2
  62. data/lib/docyard/search/dev_indexer.rb +36 -28
  63. data/lib/docyard/search/pagefind_support.rb +1 -1
  64. data/lib/docyard/server/asset_handler.rb +39 -15
  65. data/lib/docyard/server/dev_server.rb +90 -55
  66. data/lib/docyard/server/file_watcher.rb +68 -18
  67. data/lib/docyard/server/pagefind_handler.rb +1 -1
  68. data/lib/docyard/server/preview_server.rb +29 -33
  69. data/lib/docyard/server/rack_application.rb +38 -70
  70. data/lib/docyard/server/router.rb +11 -7
  71. data/lib/docyard/server/sse_server.rb +157 -0
  72. data/lib/docyard/server/static_file_app.rb +42 -0
  73. data/lib/docyard/templates/assets/css/components/banner.css +31 -0
  74. data/lib/docyard/templates/assets/css/components/breadcrumbs.css +2 -1
  75. data/lib/docyard/templates/assets/css/components/callout.css +26 -6
  76. data/lib/docyard/templates/assets/css/components/code-block.css +4 -2
  77. data/lib/docyard/templates/assets/css/components/code-group.css +20 -7
  78. data/lib/docyard/templates/assets/css/components/feedback.css +126 -0
  79. data/lib/docyard/templates/assets/css/components/file-tree.css +5 -4
  80. data/lib/docyard/templates/assets/css/components/icon.css +5 -0
  81. data/lib/docyard/templates/assets/css/components/nav-menu.css +20 -4
  82. data/lib/docyard/templates/assets/css/components/navigation.css +25 -3
  83. data/lib/docyard/templates/assets/css/components/page-actions.css +131 -0
  84. data/lib/docyard/templates/assets/css/components/prev-next.css +14 -7
  85. data/lib/docyard/templates/assets/css/components/search.css +6 -10
  86. data/lib/docyard/templates/assets/css/components/tab-bar.css +7 -4
  87. data/lib/docyard/templates/assets/css/components/table-of-contents.css +57 -11
  88. data/lib/docyard/templates/assets/css/components/tabs.css +12 -4
  89. data/lib/docyard/templates/assets/css/components/theme-toggle.css +3 -1
  90. data/lib/docyard/templates/assets/css/landing.css +82 -13
  91. data/lib/docyard/templates/assets/css/layout.css +17 -0
  92. data/lib/docyard/templates/assets/css/markdown.css +22 -2
  93. data/lib/docyard/templates/assets/css/variables.css +13 -1
  94. data/lib/docyard/templates/assets/js/components/code-group.js +4 -1
  95. data/lib/docyard/templates/assets/js/components/copy-page.js +115 -0
  96. data/lib/docyard/templates/assets/js/components/feedback.js +66 -0
  97. data/lib/docyard/templates/assets/js/components/file-tree.js +5 -5
  98. data/lib/docyard/templates/assets/js/components/navigation.js +3 -3
  99. data/lib/docyard/templates/assets/js/components/search.js +3 -3
  100. data/lib/docyard/templates/assets/js/components/table-of-contents.js +12 -6
  101. data/lib/docyard/templates/assets/js/components/tabs.js +45 -22
  102. data/lib/docyard/templates/assets/js/components/tooltip.js +4 -4
  103. data/lib/docyard/templates/assets/js/hot-reload.js +44 -0
  104. data/lib/docyard/templates/errors/404.html.erb +114 -5
  105. data/lib/docyard/templates/errors/500.html.erb +173 -10
  106. data/lib/docyard/templates/init/_sidebar.yml +36 -0
  107. data/lib/docyard/templates/init/docyard.yml +36 -0
  108. data/lib/docyard/templates/init/pages/components.md +146 -0
  109. data/lib/docyard/templates/init/pages/getting-started.md +94 -0
  110. data/lib/docyard/templates/init/pages/index.md +22 -0
  111. data/lib/docyard/templates/layouts/default.html.erb +10 -0
  112. data/lib/docyard/templates/layouts/splash.html.erb +14 -1
  113. data/lib/docyard/templates/partials/_analytics.html.erb +24 -0
  114. data/lib/docyard/templates/partials/_banner.html.erb +1 -1
  115. data/lib/docyard/templates/partials/_code_block.html.erb +1 -1
  116. data/lib/docyard/templates/partials/_feedback.html.erb +14 -0
  117. data/lib/docyard/templates/partials/_footer.html.erb +1 -1
  118. data/lib/docyard/templates/partials/_head.html.erb +79 -4
  119. data/lib/docyard/templates/partials/_icon_library.html.erb +8 -0
  120. data/lib/docyard/templates/partials/_page_actions.html.erb +21 -0
  121. data/lib/docyard/templates/partials/_scripts.html.erb +6 -3
  122. data/lib/docyard/templates/partials/_tabs.html.erb +4 -1
  123. data/lib/docyard/utils/git_info.rb +157 -0
  124. data/lib/docyard/utils/hash_utils.rb +31 -0
  125. data/lib/docyard/utils/html_helpers.rb +8 -0
  126. data/lib/docyard/utils/logging.rb +44 -3
  127. data/lib/docyard/utils/path_resolver.rb +0 -10
  128. data/lib/docyard/utils/path_utils.rb +73 -0
  129. data/lib/docyard/version.rb +1 -1
  130. data/lib/docyard.rb +2 -2
  131. metadata +77 -47
  132. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  133. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  134. data/.github/pull_request_template.md +0 -14
  135. data/.github/workflows/ci.yml +0 -49
  136. data/.rubocop.yml +0 -42
  137. data/CODE_OF_CONDUCT.md +0 -132
  138. data/CONTRIBUTING.md +0 -55
  139. data/LICENSE.vscode-icons +0 -42
  140. data/Rakefile +0 -8
  141. data/lib/docyard/config/constants.rb +0 -31
  142. data/lib/docyard/navigation/sidebar/children_discoverer.rb +0 -51
  143. data/lib/docyard/navigation/sidebar/config_parser.rb +0 -208
  144. data/lib/docyard/navigation/sidebar/file_resolver.rb +0 -90
  145. data/lib/docyard/navigation/sidebar/file_system_scanner.rb +0 -78
  146. data/lib/docyard/navigation/sidebar/metadata_extractor.rb +0 -71
  147. data/lib/docyard/navigation/sidebar/metadata_reader.rb +0 -51
  148. data/lib/docyard/navigation/sidebar/path_prefixer.rb +0 -34
  149. data/lib/docyard/navigation/sidebar/sorter.rb +0 -21
  150. data/lib/docyard/navigation/sidebar/title_extractor.rb +0 -25
  151. data/lib/docyard/navigation/sidebar/tree_builder.rb +0 -140
  152. data/lib/docyard/rendering/icons/LICENSE.phosphor +0 -21
  153. data/lib/docyard/rendering/icons/file_types.rb +0 -79
  154. data/lib/docyard/rendering/icons/phosphor.rb +0 -93
  155. data/lib/docyard/rendering/language_mapping.rb +0 -52
  156. data/lib/docyard/templates/assets/js/reload.js +0 -98
  157. data/lib/docyard/templates/partials/_icon.html.erb +0 -1
  158. data/lib/docyard/templates/partials/_icon_file_extension.html.erb +0 -1
  159. data/sig/docyard.rbs +0 -4
@@ -0,0 +1,146 @@
1
+ ---
2
+ title: Components
3
+ description: Available documentation components
4
+ ---
5
+
6
+ # Components
7
+
8
+ Docyard comes with a rich set of components to make your documentation shine.
9
+
10
+ ## Callouts
11
+
12
+ Use callouts to highlight important information:
13
+
14
+ :::note
15
+ This is a note callout for general information.
16
+ :::
17
+
18
+ :::tip
19
+ This is a tip callout for helpful suggestions.
20
+ :::
21
+
22
+ :::warning
23
+ This is a warning callout for things to watch out for.
24
+ :::
25
+
26
+ :::danger
27
+ This is a danger callout for critical warnings.
28
+ :::
29
+
30
+ ## Code Blocks
31
+
32
+ Syntax highlighting with copy button:
33
+
34
+ ```javascript
35
+ function greet(name) {
36
+ console.log(`Hello, ${name}!`);
37
+ }
38
+
39
+ greet('World');
40
+ ```
41
+
42
+ Code blocks can have titles:
43
+
44
+ ```ruby [config/routes.rb]
45
+ Rails.application.routes.draw do
46
+ root 'pages#home'
47
+ end
48
+ ```
49
+
50
+ And line highlighting:
51
+
52
+ ```python {2-3}
53
+ def calculate(x, y):
54
+ result = x + y # This line is highlighted
55
+ return result # This one too
56
+ ```
57
+
58
+ ## Code Groups
59
+
60
+ Group related code blocks with tabs:
61
+
62
+ :::code-group
63
+ ```bash [npm]
64
+ npm install my-package
65
+ ```
66
+
67
+ ```bash [yarn]
68
+ yarn add my-package
69
+ ```
70
+
71
+ ```bash [pnpm]
72
+ pnpm add my-package
73
+ ```
74
+ :::
75
+
76
+ ## Steps
77
+
78
+ Create step-by-step guides:
79
+
80
+ :::steps
81
+ ### Create a file
82
+
83
+ Create a new file called `example.md`.
84
+
85
+ ### Add content
86
+
87
+ Write your documentation content.
88
+
89
+ ### Preview
90
+
91
+ Run `docyard serve` to preview.
92
+ :::
93
+
94
+ ## Cards
95
+
96
+ Link to other pages with cards:
97
+
98
+ :::cards
99
+ ::card{title="Getting Started" icon="rocket-launch" href="/getting-started"}
100
+ Learn the basics
101
+ ::
102
+
103
+ ::card{title="Configuration" icon="code" href="/getting-started"}
104
+ Customize your site
105
+ ::
106
+ :::
107
+
108
+ ## Accordion
109
+
110
+ Collapsible content sections:
111
+
112
+ :::details{title="Click to expand"}
113
+ This content is hidden by default. Click the title to reveal it.
114
+
115
+ You can put any content here, including code blocks and other components.
116
+ :::
117
+
118
+ ## Badges
119
+
120
+ Inline status indicators: :badge[New]{type="success"} :badge[Beta]{type="warning"} :badge[Deprecated]{type="danger"}
121
+
122
+ ## File Tree
123
+
124
+ Display directory structures:
125
+
126
+ ```filetree
127
+ src/
128
+ components/
129
+ Button.jsx
130
+ Card.jsx
131
+ utils/
132
+ helpers.js
133
+ index.js
134
+ ```
135
+
136
+ ## Tables
137
+
138
+ | Feature | Status | Notes |
139
+ |---------|--------|-------|
140
+ | Markdown | Supported | Full GFM support |
141
+ | Dark Mode | Supported | Automatic |
142
+ | Search | Supported | Powered by Pagefind |
143
+
144
+ ## More Components
145
+
146
+ Docyard supports many more components. Visit the [documentation](https://docyard.dev) for the complete list.
@@ -0,0 +1,94 @@
1
+ ---
2
+ title: Getting Started
3
+ description: Get up and running with {{PROJECT_NAME}}
4
+ ---
5
+
6
+ # Getting Started
7
+
8
+ This guide will help you get started with {{PROJECT_NAME}}.
9
+
10
+ ## Prerequisites
11
+
12
+ Before you begin, make sure you have:
13
+
14
+ - Basic knowledge of Markdown
15
+ - A text editor
16
+
17
+ ## Installation
18
+
19
+ :::steps
20
+ ### Step 1: Install Docyard
21
+
22
+ ```bash
23
+ gem install docyard
24
+ ```
25
+
26
+ ### Step 2: Create a new project
27
+
28
+ ```bash
29
+ docyard init my-docs
30
+ cd my-docs
31
+ ```
32
+
33
+ ### Step 3: Start the development server
34
+
35
+ ```bash
36
+ docyard serve
37
+ ```
38
+
39
+ Open http://localhost:4200 in your browser.
40
+ :::
41
+
42
+ ## Project Structure
43
+
44
+ After initialization, your project will look like this:
45
+
46
+ ```filetree
47
+ my-docs/
48
+ docyard.yml # Configuration file
49
+ docs/
50
+ _sidebar.yml # Sidebar navigation
51
+ index.md # Home page
52
+ getting-started.md
53
+ components.md
54
+ public/ # Static assets (images, etc.)
55
+ ```
56
+
57
+ ## Writing Content
58
+
59
+ Create new pages by adding `.md` files to the `docs/` folder:
60
+
61
+ ```markdown
62
+ ---
63
+ title: My New Page
64
+ description: A brief description
65
+ ---
66
+
67
+ # My New Page
68
+
69
+ Your content here...
70
+ ```
71
+
72
+ Then add it to `_sidebar.yml`:
73
+
74
+ ```yaml
75
+ - my-new-page:
76
+ text: My New Page
77
+ icon: file
78
+ ```
79
+
80
+ ## Building for Production
81
+
82
+ When you're ready to deploy:
83
+
84
+ ```bash
85
+ docyard build
86
+ ```
87
+
88
+ This creates a `dist/` folder with static HTML files ready to deploy anywhere.
89
+
90
+ ## Next Steps
91
+
92
+ - Explore the [Components](/components) page to see what's available
93
+ - Configure your site in `docyard.yml`
94
+ - Deploy to GitHub Pages, Vercel, or Netlify
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: Welcome
3
+ description: Welcome to {{PROJECT_NAME}}
4
+ landing:
5
+ hero:
6
+ title: "{{PROJECT_NAME}}"
7
+ tagline: "Beautiful documentation, built with Docyard"
8
+ actions:
9
+ - text: Get Started
10
+ link: /getting-started
11
+ variant: primary
12
+ features:
13
+ - title: Fast & Simple
14
+ description: Write in Markdown, get a beautiful site. No configuration required.
15
+ icon: rocket-launch
16
+ - title: Dark Mode
17
+ description: Automatic dark mode that respects system preferences.
18
+ icon: moon
19
+ - title: Full-Text Search
20
+ description: Built-in search powered by Pagefind. Works offline.
21
+ icon: magnifying-glass
22
+ ---
@@ -30,6 +30,12 @@
30
30
  <%= render_partial('_breadcrumbs') %>
31
31
  <%= @content %>
32
32
 
33
+ <div class="page-actions-mobile">
34
+ <%= render_partial('_page_actions') %>
35
+ </div>
36
+
37
+ <%= render_partial('_feedback') %>
38
+
33
39
  <%= @prev_next_html %>
34
40
 
35
41
  <div class="doc-footer-mobile">
@@ -41,11 +47,15 @@
41
47
  <aside class="doc-aside">
42
48
  <%= render_partial('_table_of_contents') %>
43
49
  <div class="doc-footer-desktop">
50
+ <%= render_partial('_page_actions') %>
44
51
  <%= render_partial('_doc_footer') %>
45
52
  </div>
46
53
  </aside>
47
54
  </div>
48
55
 
56
+ <% if @raw_markdown %>
57
+ <script id="page-markdown" type="application/json"><%= @raw_markdown.to_json %></script>
58
+ <% end %>
49
59
  <%= render_partial('_scripts') %>
50
60
  </body>
51
61
  </html>
@@ -30,7 +30,10 @@
30
30
  <main id="main-content" class="splash-content">
31
31
  <% if @hero %>
32
32
  <%
33
- hero_class = @hero[:image] ? 'hero hero--with-image' : 'hero hero--centered'
33
+ has_side_visual = @hero[:image] || (@hero[:custom_visual] && @hero[:custom_visual][:placement] == 'side')
34
+ has_bottom_visual = @hero[:custom_visual] && @hero[:custom_visual][:placement] == 'bottom'
35
+ hero_class = has_side_visual ? 'hero hero--with-image' : 'hero hero--centered'
36
+ hero_class += ' hero--with-bottom-visual' if has_bottom_visual
34
37
  bg_style = @hero[:background] || 'grid'
35
38
  %>
36
39
  <section class="<%= hero_class %>">
@@ -100,8 +103,18 @@
100
103
  <% end %>
101
104
  </div>
102
105
  <% end %>
106
+ <% if @hero[:custom_visual] && @hero[:custom_visual][:placement] == 'side' %>
107
+ <div class="hero-custom-visual hero-custom-visual--side">
108
+ <%= render_custom_visual(@hero[:custom_visual][:html]) %>
109
+ </div>
110
+ <% end %>
103
111
 
104
112
  </section>
113
+ <% if @hero[:custom_visual] && @hero[:custom_visual][:placement] == 'bottom' %>
114
+ <div class="hero-custom-visual hero-custom-visual--bottom">
115
+ <%= render_custom_visual(@hero[:custom_visual][:html]) %>
116
+ </div>
117
+ <% end %>
105
118
  <% end %>
106
119
 
107
120
  <% if @features&.any? %>
@@ -0,0 +1,24 @@
1
+ <% if @has_analytics %>
2
+ <% if @analytics_google %>
3
+ <link rel="preconnect" href="https://www.googletagmanager.com" crossorigin>
4
+ <link rel="preconnect" href="https://www.google-analytics.com" crossorigin>
5
+ <script async src="https://www.googletagmanager.com/gtag/js?id=<%= @analytics_google %>"></script>
6
+ <script>
7
+ window.dataLayer = window.dataLayer || [];
8
+ function gtag(){dataLayer.push(arguments);}
9
+ gtag('js', new Date());
10
+ gtag('config', '<%= @analytics_google %>');
11
+ </script>
12
+ <% end %>
13
+ <% if @analytics_plausible %>
14
+ <link rel="preconnect" href="https://plausible.io" crossorigin>
15
+ <script defer data-domain="<%= @analytics_plausible %>" src="https://plausible.io/js/script.js"></script>
16
+ <% end %>
17
+ <% if @analytics_fathom %>
18
+ <link rel="preconnect" href="https://cdn.usefathom.com" crossorigin>
19
+ <script src="https://cdn.usefathom.com/script.js" data-site="<%= @analytics_fathom %>" defer></script>
20
+ <% end %>
21
+ <% if @analytics_script %>
22
+ <script defer src="<%= asset_path(@analytics_script) %>"></script>
23
+ <% end %>
24
+ <% end %>
@@ -23,5 +23,5 @@
23
23
  </button>
24
24
  <% end %>
25
25
  </div>
26
- <script>document.body.classList.add('has-announcement');</script>
26
+ <script>if(!document.documentElement.classList.contains('banner-dismissed'))document.body.classList.add('has-announcement');</script>
27
27
  <% end %>
@@ -2,7 +2,7 @@
2
2
  <% if has_title %>
3
3
  <div class="docyard-code-block__header">
4
4
  <% if @icon %>
5
- <span class="docyard-code-block__icon"><% if @icon_source == "file-extension" %><%= icon_file_extension(@icon) %><% elsif @icon_source == "phosphor" %><%= icon(@icon) %><% end %></span>
5
+ <span class="docyard-code-block__icon"><% if @icon_source == "language" %><%= icon_for_language(@icon) %><% elsif @icon_source == "file-extension" %><%= icon_file_extension(@icon) %><% elsif @icon_source == "phosphor" %><%= icon(@icon) %><% end %></span>
6
6
  <% end %>
7
7
  <span class="docyard-code-block__title" title="<%= @title %>"><%= @title %></span>
8
8
  <button class="docyard-code-block__copy" aria-label="Copy code to clipboard" data-code="<%= @code_text %>">
@@ -0,0 +1,14 @@
1
+ <% if @feedback_enabled %>
2
+ <div class="feedback" data-pagefind-ignore>
3
+ <p class="feedback__question"><%= @feedback_question %></p>
4
+ <div class="feedback__buttons">
5
+ <button type="button" class="feedback__btn" data-feedback="yes" aria-label="Yes, this page was helpful">
6
+ <%= icon(:thumbs_up) %>
7
+ </button>
8
+ <button type="button" class="feedback__btn" data-feedback="no" aria-label="No, this page was not helpful">
9
+ <%= icon(:thumbs_down) %>
10
+ </button>
11
+ </div>
12
+ <p class="feedback__thanks" aria-live="polite" hidden>Thanks for your feedback!</p>
13
+ </div>
14
+ <% end %>
@@ -17,7 +17,7 @@
17
17
  %>
18
18
  <div class="<%= footer_class %>">
19
19
  <% if @credits %>
20
- <a href="https://docyard.org" target="_blank" rel="noopener noreferrer" class="footer-attribution">Built with Docyard</a>
20
+ <a href="https://docyard.dev" target="_blank" rel="noopener noreferrer" class="footer-attribution">Built with Docyard</a>
21
21
  <% end %>
22
22
 
23
23
  <% if has_footer_links %>
@@ -5,18 +5,93 @@
5
5
  <title><%= @page_title %> | <%= @site_title %></title>
6
6
  <link rel="icon" href="<%= asset_path(@favicon) %>" type="image/svg+xml">
7
7
 
8
+ <% if @og_enabled %>
9
+ <link rel="canonical" href="<%= @og_url %>">
10
+
11
+ <meta property="og:type" content="website">
12
+ <meta property="og:site_name" content="<%= @site_title %>">
13
+ <meta property="og:title" content="<%= @page_title %>">
14
+ <meta property="og:url" content="<%= @og_url %>">
15
+ <% if @og_description && !@og_description.empty? %>
16
+ <meta property="og:description" content="<%= @og_description %>">
17
+ <% end %>
18
+ <% if @og_image %>
19
+ <meta property="og:image" content="<%= @og_image %>">
20
+ <% end %>
21
+
22
+ <meta name="twitter:card" content="<%= @og_image ? 'summary_large_image' : 'summary' %>">
23
+ <meta name="twitter:title" content="<%= @page_title %>">
24
+ <% if @og_description && !@og_description.empty? %>
25
+ <meta name="twitter:description" content="<%= @og_description %>">
26
+ <% end %>
27
+ <% if @og_image %>
28
+ <meta name="twitter:image" content="<%= @og_image %>">
29
+ <% end %>
30
+ <% if @og_twitter %>
31
+ <meta name="twitter:site" content="@<%= @og_twitter.delete_prefix('@') %>">
32
+ <% end %>
33
+ <% end %>
34
+
8
35
  <link rel="preload" href="/_docyard/fonts/Inter-Variable.ttf" as="font" type="font/ttf" crossorigin>
9
36
 
37
+ <%= render_partial('_icon_library') %>
38
+
10
39
  <script>
11
40
  (function() {
12
- const theme = localStorage.getItem('theme') ||
13
- (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
14
- document.documentElement.classList.toggle('dark', theme === 'dark');
41
+ var html = document.documentElement;
42
+
43
+ html.classList.add('no-transition');
44
+
45
+ var theme = localStorage.getItem('theme') ||
46
+ (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
47
+ html.classList.toggle('dark', theme === 'dark');
15
48
 
16
49
  if (localStorage.getItem('docyard_sidebar_collapsed') === 'true') {
17
- document.documentElement.classList.add('sidebar-collapsed');
50
+ html.classList.add('sidebar-collapsed');
18
51
  }
52
+
53
+ var BANNER_KEY = 'docyard-announcement-dismissed';
54
+ try {
55
+ var dismissed = localStorage.getItem(BANNER_KEY);
56
+ if (dismissed) {
57
+ var dismissedAt = parseInt(dismissed, 10);
58
+ var sevenDaysAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
59
+ if (dismissedAt > sevenDaysAgo) {
60
+ html.classList.add('banner-dismissed');
61
+ }
62
+ }
63
+ } catch (e) {}
64
+
65
+ requestAnimationFrame(function() {
66
+ requestAnimationFrame(function() {
67
+ html.classList.remove('no-transition');
68
+ });
69
+ });
19
70
  })();
20
71
  </script>
21
72
 
22
73
  <link rel="stylesheet" href="/_docyard/css/main.css">
74
+
75
+ <% if @primary_color && (@primary_color[:light] || @primary_color[:dark]) %>
76
+ <style>
77
+ <% light_color = @primary_color[:light] %>
78
+ <% dark_color = @primary_color[:dark] || light_color %>
79
+ <% if light_color %>
80
+ :root {
81
+ --primary: <%= light_color %>;
82
+ --sidebar-primary: <%= light_color %>;
83
+ }
84
+ .dark {
85
+ --primary: <%= dark_color %>;
86
+ --sidebar-primary: <%= dark_color %>;
87
+ }
88
+ <% elsif dark_color %>
89
+ .dark {
90
+ --primary: <%= dark_color %>;
91
+ --sidebar-primary: <%= dark_color %>;
92
+ }
93
+ <% end %>
94
+ </style>
95
+ <% end %>
96
+
97
+ <%= render_partial('_analytics') %>
@@ -0,0 +1,8 @@
1
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/regular/style.css">
2
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/bold/style.css">
3
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/fill/style.css">
4
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/light/style.css">
5
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/thin/style.css">
6
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/duotone/style.css">
7
+
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/devicon.min.css">
@@ -0,0 +1,21 @@
1
+ <% if @raw_markdown || @show_edit_link || @show_last_updated %>
2
+ <div class="page-actions">
3
+ <% if @raw_markdown %>
4
+ <button type="button" class="page-actions__copy-btn" data-copy-page>
5
+ <%= icon(:copy) %>
6
+ <span class="page-actions__copy-text">Copy page</span>
7
+ </button>
8
+ <% end %>
9
+ <% if @show_edit_link && @edit_url %>
10
+ <a href="<%= @edit_url %>" class="page-actions__edit-link" target="_blank" rel="noopener noreferrer">
11
+ <%= icon(:pencil_simple_line) %>
12
+ Edit this page
13
+ </a>
14
+ <% end %>
15
+ <% if @show_last_updated && @last_updated %>
16
+ <div class="page-actions__last-updated">
17
+ Last updated <time datetime="<%= @last_updated[:iso] %>" title="<%= @last_updated[:formatted] %>"><%= @last_updated[:relative] %></time>
18
+ </div>
19
+ <% end %>
20
+ </div>
21
+ <% end %>
@@ -2,6 +2,9 @@
2
2
  <%= render_partial('_search_modal') %>
3
3
  <% end %>
4
4
 
5
- <script src="/_docyard/js/theme.js"></script>
6
- <script src="/_docyard/js/components.js"></script>
7
- <script src="/_docyard/js/reload.js"></script>
5
+ <script src="/_docyard/js/theme.js" defer></script>
6
+ <script src="/_docyard/js/components.js" defer></script>
7
+ <% if @dev_mode %>
8
+ <script>window.__DOCYARD_SSE_PORT__ = <%= @sse_port %>;</script>
9
+ <script src="/_docyard/js/hot-reload.js" defer></script>
10
+ <% end %>
@@ -9,10 +9,13 @@
9
9
  id="tab-<%= @group_id %>-<%= index %>"
10
10
  class="docyard-tabs__tab"
11
11
  tabindex="<%= index == 0 ? '0' : '-1' %>"
12
+ data-tab-name="<%= tab[:name].downcase %>"
12
13
  >
13
14
  <% if tab[:icon] %>
14
15
  <span class="docyard-tabs__icon">
15
- <% if tab[:icon_source] == "file-extension" %>
16
+ <% if tab[:icon_source] == "language" %>
17
+ <%= icon_for_language(tab[:icon]) %>
18
+ <% elsif tab[:icon_source] == "file-extension" %>
16
19
  <%= icon_file_extension(tab[:icon]) %>
17
20
  <% elsif tab[:icon_source] == "phosphor" %>
18
21
  <%= icon(tab[:icon]) %>