howdoc 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +33 -0
- data/config/locales/howdoc.en.yml +5 -0
- data/config/locales/howdoc.et.yml +5 -0
- data/lib/howdoc/narrator.rb +8 -0
- data/lib/howdoc/navigation.rb +118 -0
- data/lib/howdoc/registry.rb +13 -3
- data/lib/howdoc/version.rb +1 -1
- data/lib/howdoc/writers.rb +2 -2
- data/lib/howdoc.rb +1 -0
- data/templates/default/assets/howdoc.css +107 -7
- data/templates/default/document/html/layout.haml +6 -1
- data/templates/default/index/html/layout.haml +8 -13
- data/templates/default/shared/html/nav.haml +25 -0
- data/templates/default/shared/html/pager.haml +11 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 72edea92225be55592acd2d56c732d5d82e140193b06dc276b0c691440ff2e3f
|
|
4
|
+
data.tar.gz: 2ec1eea553ec1b5ca6e23f9f320e082367ded34280cf6701e8f284f06f1ef34c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9692dcfc9505fa3cf80eff5ea7a6c2dcb244619a41aa163cbab98c04a16b01bb13d82d646db46b1e98025f386a47594553abfd4b59a6e937040b555a6f9ecadb
|
|
7
|
+
data.tar.gz: 8ee1913418a639198f1134958ce9748ff83a231a5d86b8fb237675ab264d62b50ad9f5cdfd9e8433310b0c6c226bbf35ec6a21d9afd22c5eee0884b6b9042c86
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
Every page now carries the menu, so a guide opened from a link is a whole page
|
|
6
|
+
rather than a dead end, and a documentation set no longer needs a frame to hold
|
|
7
|
+
its navigation together.
|
|
8
|
+
|
|
9
|
+
- A guide leaves an empty `<nav data-howdoc-nav>`, and the index pass fills it
|
|
10
|
+
in once every guide is on disk -- a guide cannot draw a menu of guides when it
|
|
11
|
+
is written, because no other guide exists yet. A template without the
|
|
12
|
+
placeholder is left exactly as it was.
|
|
13
|
+
- The same pass writes previous/next links into `<nav data-howdoc-pager>`.
|
|
14
|
+
- The menu links the same guide in the other languages, matched by identifier,
|
|
15
|
+
since a translated heading gives a translated file name. Each language names
|
|
16
|
+
itself in its own language.
|
|
17
|
+
- `config.group_label` now heads sections in the menu as well as the index.
|
|
18
|
+
- The index carries `howdoc.index.intro` when an application translates it, so
|
|
19
|
+
the landing page can say something of its own without a hand-kept file.
|
|
20
|
+
- Templates read the gem's own words through a lookup an application's I18n
|
|
21
|
+
cascade cannot answer with something unrelated.
|
|
22
|
+
|
|
3
23
|
## 0.2.0
|
|
4
24
|
|
|
5
25
|
Guides are now written in every language the application publishes, from a
|
data/README.md
CHANGED
|
@@ -212,6 +212,39 @@ naming the language it is missing from, rather than leaving a silent hole in the
|
|
|
212
212
|
guide. A step no language can describe is not recorded at all; a step one
|
|
213
213
|
language cannot describe is left out of that language's guide only.
|
|
214
214
|
|
|
215
|
+
## Navigation
|
|
216
|
+
|
|
217
|
+
Every page carries the menu, and a guide links the ones before and after it:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
public/docs/en/how_to_add_a_claim.html
|
|
221
|
+
┌────────────┬────────────────────┐
|
|
222
|
+
│ Guides │ 1.3. How to add a … │
|
|
223
|
+
│ EVERYDAY │ 1. Log in … │
|
|
224
|
+
│ 1.1 … │ [screenshot] │
|
|
225
|
+
│ 1.3 ● │ ‹ Previous Next › │
|
|
226
|
+
└────────────┴────────────────────┘
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
A guide cannot draw that menu when it is written: tests run in forked workers,
|
|
230
|
+
each one writes its own page, and no other guide exists yet. So the guide leaves
|
|
231
|
+
an empty placeholder and the index pass -- which has just read every page back
|
|
232
|
+
-- fills it in:
|
|
233
|
+
|
|
234
|
+
```haml
|
|
235
|
+
%nav.howdoc-nav{ data: { howdoc_nav: true } } -# the menu
|
|
236
|
+
%nav.howdoc-pager{ data: { howdoc_pager: true } } -# previous / next
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Both are optional. A template that carries neither is left exactly as it is.
|
|
240
|
+
|
|
241
|
+
The menu also links the same guide in every other language the application
|
|
242
|
+
publishes. Guides are matched by their identifier rather than their file name,
|
|
243
|
+
because a translated heading gives a translated file name, and each language
|
|
244
|
+
names itself in its own language (`howdoc.languages.<code>`).
|
|
245
|
+
|
|
246
|
+
`config.group_label` heads the sections, in the menu and in the index alike.
|
|
247
|
+
|
|
215
248
|
## Templates
|
|
216
249
|
|
|
217
250
|
Page chrome lives in templates, never in the code that records steps, so
|
|
@@ -19,6 +19,11 @@ en:
|
|
|
19
19
|
visit: Open <strong>%{url}</strong> in your browser.
|
|
20
20
|
document:
|
|
21
21
|
follow_steps: 'Follow these steps:'
|
|
22
|
+
languages:
|
|
23
|
+
en: English
|
|
24
|
+
pager:
|
|
25
|
+
next: Next
|
|
26
|
+
previous: Previous
|
|
22
27
|
index:
|
|
23
28
|
empty: No guides have been generated yet.
|
|
24
29
|
title: Guides
|
|
@@ -19,6 +19,11 @@ et:
|
|
|
19
19
|
visit: Palun sisesta <strong>%{url}</strong> oma brauserisse.
|
|
20
20
|
document:
|
|
21
21
|
follow_steps: 'Palun jälgige järgnevaid samme:'
|
|
22
|
+
languages:
|
|
23
|
+
et: Eesti
|
|
24
|
+
pager:
|
|
25
|
+
next: Järgmine
|
|
26
|
+
previous: Eelmine
|
|
22
27
|
index:
|
|
23
28
|
empty: Ühtegi juhendit ei ole veel loodud.
|
|
24
29
|
title: Juhendid
|
data/lib/howdoc/narrator.rb
CHANGED
|
@@ -95,6 +95,14 @@ module Howdoc
|
|
|
95
95
|
lookup(DOCUMENTS, key, field, locale:) || default
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
# The gem's own words -- the ones its templates print rather than the ones
|
|
99
|
+
# it narrates a step with. Looked up the safe way, so an application whose
|
|
100
|
+
# I18n cascades cannot answer an untranslated "howdoc.index.intro" with
|
|
101
|
+
# some unrelated top-level "intro" of its own.
|
|
102
|
+
def phrase(*path, locale:, default: nil)
|
|
103
|
+
lookup(*path, locale:) || default
|
|
104
|
+
end
|
|
105
|
+
|
|
98
106
|
# Rails names fields after the model that owns them, which is noise to
|
|
99
107
|
# anyone who does not know the schema, so the leading segment is dropped.
|
|
100
108
|
def humanize_locator(locator)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Howdoc
|
|
4
|
+
# The menu, and the links from one guide to the next.
|
|
5
|
+
#
|
|
6
|
+
# A guide is written the moment its test finishes, when no other guide is
|
|
7
|
+
# known yet -- tests run in forked workers and each one writes its own page --
|
|
8
|
+
# so a guide cannot draw a menu of guides. It leaves an empty <nav> instead,
|
|
9
|
+
# and this fills it in at the end of the run, when the index has just read
|
|
10
|
+
# every page back and knows what there is.
|
|
11
|
+
#
|
|
12
|
+
# Filling in rather than re-rendering: the steps a guide was made of are long
|
|
13
|
+
# gone by then, but its page is not, and this gem wrote that page. Running the
|
|
14
|
+
# pass again simply replaces what it wrote the last time.
|
|
15
|
+
#
|
|
16
|
+
# A template that carries no placeholder is left exactly as it is, so an
|
|
17
|
+
# application with its own page chrome loses nothing by not having one.
|
|
18
|
+
module Navigation
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
|
+
# Writes the menu and the pager into every guide. +by_locale+ is the sorted
|
|
22
|
+
# records the index was built from, so the menu lists the guides in the same
|
|
23
|
+
# order the index does.
|
|
24
|
+
def install(by_locale, root: Howdoc.config.root)
|
|
25
|
+
by_locale.each_value.flat_map do |records|
|
|
26
|
+
records.each_with_index.filter_map do |record, position|
|
|
27
|
+
write(record, records:, position:, by_locale:, root:)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def write(record, records:, position:, by_locale:, root:)
|
|
33
|
+
path = File.join(root, record.locale.to_s, record.filename)
|
|
34
|
+
return nil unless File.file?(path)
|
|
35
|
+
|
|
36
|
+
markup = File.read(path)
|
|
37
|
+
filled = fill(markup, :nav) { nav(record, records, by_locale) }
|
|
38
|
+
filled = fill(filled, :pager) { pager(record, records, position) }
|
|
39
|
+
return nil if filled == markup
|
|
40
|
+
|
|
41
|
+
File.write(path, filled)
|
|
42
|
+
path
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Stripped, so that filling a page in a second time leaves it exactly as the
|
|
46
|
+
# first time left it: the pass runs once per suite and again at the end of a
|
|
47
|
+
# run, and a page that grew a blank line each time would show up as changed
|
|
48
|
+
# in a repository for no reason at all.
|
|
49
|
+
def fill(markup, name)
|
|
50
|
+
markup.sub(placeholder(name)) { yield.strip }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def placeholder(name)
|
|
54
|
+
%r{<nav[^>]*data-howdoc-#{name}[^>]*>.*?</nav>}m
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def nav(record, records, by_locale)
|
|
58
|
+
Templates.render(
|
|
59
|
+
'shared/html/nav.haml',
|
|
60
|
+
locale: record.locale, records:, current: record, config: Howdoc.config,
|
|
61
|
+
languages: languages(current_locale: record.locale, record:, by_locale:)
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def pager(record, records, position)
|
|
66
|
+
Templates.render(
|
|
67
|
+
'shared/html/pager.haml',
|
|
68
|
+
locale: record.locale, config: Howdoc.config,
|
|
69
|
+
previous: (records[position - 1] if position.positive?),
|
|
70
|
+
next: records[position + 1]
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# The same guide in the other languages the application publishes.
|
|
75
|
+
#
|
|
76
|
+
# Matched by identifier rather than by file name: a guide with a translated
|
|
77
|
+
# heading gets a translated file name, so "1.3" is the only thing the two
|
|
78
|
+
# pages are sure to have in common. A guide that was never written in the
|
|
79
|
+
# other language points at that language's index instead of nowhere.
|
|
80
|
+
def languages(current_locale:, by_locale:, record: nil)
|
|
81
|
+
ordered(by_locale.keys).map do |locale|
|
|
82
|
+
current = locale.to_s == current_locale.to_s
|
|
83
|
+
|
|
84
|
+
{
|
|
85
|
+
code: locale.to_s,
|
|
86
|
+
label: label(locale),
|
|
87
|
+
current:,
|
|
88
|
+
href: (destination(locale, record, by_locale) unless current)
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def destination(locale, record, by_locale)
|
|
94
|
+
counterpart = record && counterpart(record, by_locale[locale] || [])
|
|
95
|
+
|
|
96
|
+
"../#{locale}/#{counterpart ? counterpart.filename : Registry::INDEX_FILENAME}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def counterpart(record, records)
|
|
100
|
+
return records.find { |other| other.id == record.id } unless record.id.nil?
|
|
101
|
+
|
|
102
|
+
records.find { |other| other.permalink == record.permalink }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# A language names itself in its own language, which is how a reader who
|
|
106
|
+
# cannot read the current page still recognises the way out of it.
|
|
107
|
+
def label(locale)
|
|
108
|
+
Narrator.phrase(:languages, locale, locale:, default: locale.to_s.upcase)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def ordered(locales)
|
|
112
|
+
configured = Howdoc.config.locales&.map(&:to_s)
|
|
113
|
+
return locales.map(&:to_s).sort if configured.nil?
|
|
114
|
+
|
|
115
|
+
(configured & locales.map(&:to_s)) | locales.map(&:to_s).sort
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
data/lib/howdoc/registry.rb
CHANGED
|
@@ -80,13 +80,23 @@ module Howdoc
|
|
|
80
80
|
Howdoc.config.locales.to_h { |locale| [locale.to_s, found.fetch(locale.to_s, [])] }
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
# Builds the index for every locale that produced at least one guide
|
|
83
|
+
# Builds the index for every locale that produced at least one guide, and
|
|
84
|
+
# then writes the menu into the guides themselves: they were written one at
|
|
85
|
+
# a time, before there was a menu to draw.
|
|
84
86
|
def write_indexes(root = Howdoc.config.root)
|
|
85
87
|
Templates.install_assets(File.join(root, 'assets')) if Howdoc.config.install_assets
|
|
86
88
|
|
|
87
|
-
by_locale(root).
|
|
88
|
-
|
|
89
|
+
catalogue = by_locale(root).transform_values { |records| sort(records) }
|
|
90
|
+
|
|
91
|
+
written = catalogue.map do |locale, records|
|
|
92
|
+
Writers::Index.call(
|
|
93
|
+
locale:, records:, root:,
|
|
94
|
+
languages: Navigation.languages(current_locale: locale, by_locale: catalogue)
|
|
95
|
+
)
|
|
89
96
|
end
|
|
97
|
+
|
|
98
|
+
Navigation.install(catalogue, root:)
|
|
99
|
+
written
|
|
90
100
|
end
|
|
91
101
|
|
|
92
102
|
def sort(records)
|
data/lib/howdoc/version.rb
CHANGED
data/lib/howdoc/writers.rb
CHANGED
|
@@ -70,13 +70,13 @@ module Howdoc
|
|
|
70
70
|
|
|
71
71
|
# Writes one index per locale, from the guides the run just produced.
|
|
72
72
|
class Index
|
|
73
|
-
def self.call(locale:, records:, root: Howdoc.config.root)
|
|
73
|
+
def self.call(locale:, records:, root: Howdoc.config.root, languages: [])
|
|
74
74
|
dir = File.join(root, locale.to_s)
|
|
75
75
|
FileUtils.mkdir_p(dir)
|
|
76
76
|
|
|
77
77
|
markup = Templates.render(
|
|
78
78
|
'index/html/layout.haml',
|
|
79
|
-
locale:, records:, config: Howdoc.config
|
|
79
|
+
locale:, records:, languages:, config: Howdoc.config
|
|
80
80
|
)
|
|
81
81
|
path = File.join(dir, 'index.html')
|
|
82
82
|
File.write(path, markup)
|
data/lib/howdoc.rb
CHANGED
|
@@ -13,6 +13,7 @@ require_relative 'howdoc/screenshot'
|
|
|
13
13
|
require_relative 'howdoc/recorder'
|
|
14
14
|
require_relative 'howdoc/templates'
|
|
15
15
|
require_relative 'howdoc/writers'
|
|
16
|
+
require_relative 'howdoc/navigation'
|
|
16
17
|
require_relative 'howdoc/registry'
|
|
17
18
|
|
|
18
19
|
# Generates end-user documentation from Capybara system tests.
|
|
@@ -27,7 +27,6 @@ body.howdoc {
|
|
|
27
27
|
|
|
28
28
|
.howdoc-document,
|
|
29
29
|
.howdoc-index {
|
|
30
|
-
max-width: 52rem;
|
|
31
30
|
margin: 0 auto;
|
|
32
31
|
padding: 3rem 1.25rem 6rem;
|
|
33
32
|
}
|
|
@@ -57,12 +56,6 @@ body.howdoc {
|
|
|
57
56
|
padding-left: 0.25rem;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
.howdoc-step.howdoc-arrival {
|
|
61
|
-
border-left: 3px solid var(--howdoc-accent);
|
|
62
|
-
margin-left: -1rem;
|
|
63
|
-
padding-left: 1rem;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
59
|
.howdoc-shot {
|
|
67
60
|
display: block;
|
|
68
61
|
max-width: 100%;
|
|
@@ -103,7 +96,114 @@ body.howdoc {
|
|
|
103
96
|
text-decoration: underline;
|
|
104
97
|
}
|
|
105
98
|
|
|
99
|
+
/* The menu sits beside the page it belongs to, and above it when there is no
|
|
100
|
+
room beside. A guide written before the index pass has an empty menu, and an
|
|
101
|
+
empty menu is no menu at all. */
|
|
102
|
+
.howdoc-nav:empty,
|
|
103
|
+
.howdoc-pager:empty {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.howdoc-nav {
|
|
108
|
+
padding: 1.5rem 1.25rem;
|
|
109
|
+
border-bottom: 1px solid var(--howdoc-rule);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@media (min-width: 60rem) {
|
|
113
|
+
body.howdoc {
|
|
114
|
+
display: grid;
|
|
115
|
+
grid-template-columns: 19rem minmax(0, 1fr);
|
|
116
|
+
align-items: start;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.howdoc-nav {
|
|
120
|
+
position: sticky;
|
|
121
|
+
top: 0;
|
|
122
|
+
max-height: 100vh;
|
|
123
|
+
overflow-y: auto;
|
|
124
|
+
padding: 2rem 1.25rem 3rem;
|
|
125
|
+
border-right: 1px solid var(--howdoc-rule);
|
|
126
|
+
border-bottom: 0;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.howdoc-nav-head {
|
|
131
|
+
display: flex;
|
|
132
|
+
align-items: baseline;
|
|
133
|
+
justify-content: space-between;
|
|
134
|
+
gap: 1rem;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.howdoc-nav-home {
|
|
138
|
+
color: var(--howdoc-fg);
|
|
139
|
+
font-weight: 600;
|
|
140
|
+
text-decoration: none;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.howdoc-languages {
|
|
144
|
+
display: flex;
|
|
145
|
+
gap: 0.5rem;
|
|
146
|
+
margin: 0;
|
|
147
|
+
padding: 0;
|
|
148
|
+
list-style: none;
|
|
149
|
+
font-size: 0.85rem;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.howdoc-language a {
|
|
153
|
+
color: var(--howdoc-accent);
|
|
154
|
+
text-decoration: none;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.howdoc-language.howdoc-current {
|
|
158
|
+
color: var(--howdoc-muted);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.howdoc-toc-entry.howdoc-current > a {
|
|
162
|
+
color: var(--howdoc-fg);
|
|
163
|
+
font-weight: 600;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.howdoc-pager {
|
|
167
|
+
display: flex;
|
|
168
|
+
gap: 1rem;
|
|
169
|
+
margin-top: 3rem;
|
|
170
|
+
padding-top: 1.5rem;
|
|
171
|
+
border-top: 1px solid var(--howdoc-rule);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.howdoc-pager-link {
|
|
175
|
+
display: flex;
|
|
176
|
+
flex: 1 1 0;
|
|
177
|
+
flex-direction: column;
|
|
178
|
+
gap: 0.25rem;
|
|
179
|
+
padding: 0.9rem 1rem;
|
|
180
|
+
border: 1px solid var(--howdoc-rule);
|
|
181
|
+
border-radius: 8px;
|
|
182
|
+
text-decoration: none;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.howdoc-pager-next {
|
|
186
|
+
margin-left: auto;
|
|
187
|
+
text-align: right;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.howdoc-pager-label {
|
|
191
|
+
color: var(--howdoc-muted);
|
|
192
|
+
font-size: 0.8rem;
|
|
193
|
+
letter-spacing: 0.08em;
|
|
194
|
+
text-transform: uppercase;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.howdoc-pager-heading {
|
|
198
|
+
color: var(--howdoc-accent);
|
|
199
|
+
}
|
|
200
|
+
|
|
106
201
|
@media print {
|
|
202
|
+
.howdoc-nav,
|
|
203
|
+
.howdoc-pager {
|
|
204
|
+
display: none;
|
|
205
|
+
}
|
|
206
|
+
|
|
107
207
|
.howdoc-shot {
|
|
108
208
|
box-shadow: none;
|
|
109
209
|
}
|
|
@@ -6,11 +6,16 @@
|
|
|
6
6
|
%title= @document.heading
|
|
7
7
|
%link{ rel: 'stylesheet', href: '../assets/howdoc.css' }
|
|
8
8
|
%body.howdoc
|
|
9
|
+
-# Empty on purpose: the index pass writes the menu and the pager in here
|
|
10
|
+
-# once it knows what the other guides are. A page is a whole page either
|
|
11
|
+
-# way, so a guide opened straight from a link is never a dead end.
|
|
12
|
+
%nav.howdoc-nav{ data: { howdoc_nav: true } }
|
|
9
13
|
%main.howdoc-document
|
|
10
14
|
%h1= @document.heading
|
|
11
15
|
- unless @document.intro.to_s.strip.empty?
|
|
12
16
|
.howdoc-intro!= @document.intro
|
|
13
|
-
%p.howdoc-lede=
|
|
17
|
+
%p.howdoc-lede= Howdoc::Narrator.phrase(:document, :follow_steps, locale: @document.locale)
|
|
14
18
|
%ol.howdoc-steps
|
|
15
19
|
- @document.steps.reject(&:empty?).each do |step|
|
|
16
20
|
!= render('document/html/step.haml', step: step)
|
|
21
|
+
%nav.howdoc-pager{ data: { howdoc_pager: true } }
|
|
@@ -3,20 +3,15 @@
|
|
|
3
3
|
%head
|
|
4
4
|
%meta{ charset: 'utf-8' }
|
|
5
5
|
%meta{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
|
6
|
-
%title=
|
|
6
|
+
%title= Howdoc::Narrator.phrase(:index, :title, locale: @locale)
|
|
7
7
|
%link{ rel: 'stylesheet', href: '../assets/howdoc.css' }
|
|
8
8
|
%body.howdoc
|
|
9
|
+
-# The index knows every guide already, so it draws the menu itself.
|
|
10
|
+
!= render('shared/html/nav.haml', current: nil)
|
|
9
11
|
%main.howdoc-index
|
|
10
|
-
%h1=
|
|
12
|
+
%h1= Howdoc::Narrator.phrase(:index, :title, locale: @locale)
|
|
13
|
+
- intro = Howdoc::Narrator.phrase(:index, :intro, locale: @locale)
|
|
14
|
+
- if intro
|
|
15
|
+
.howdoc-intro!= intro
|
|
11
16
|
- if @records.empty?
|
|
12
|
-
%p=
|
|
13
|
-
- else
|
|
14
|
-
%ul.howdoc-toc
|
|
15
|
-
- previous_group = nil
|
|
16
|
-
- @records.each do |record|
|
|
17
|
-
- group = @config.group_label.call(record)
|
|
18
|
-
- if group && group != previous_group
|
|
19
|
-
%li.howdoc-toc-group= group
|
|
20
|
-
- previous_group = group
|
|
21
|
-
%li.howdoc-toc-entry
|
|
22
|
-
%a{ href: "./#{record.filename}" }= record.heading
|
|
17
|
+
%p= Howdoc::Narrator.phrase(:index, :empty, locale: @locale)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-# The menu every page carries. A guide cannot draw this when it is written --
|
|
2
|
+
-# no other guide exists yet -- so a guide leaves the empty <nav> below and the
|
|
3
|
+
-# index pass fills it in once every guide is on disk. The index renders it
|
|
4
|
+
-# directly, because by then it knows.
|
|
5
|
+
%nav.howdoc-nav{ data: { howdoc_nav: true } }
|
|
6
|
+
.howdoc-nav-head
|
|
7
|
+
%a.howdoc-nav-home{ href: './index.html' }= Howdoc::Narrator.phrase(:index, :title, locale: @locale)
|
|
8
|
+
- if @languages.size > 1
|
|
9
|
+
%ul.howdoc-languages
|
|
10
|
+
- @languages.each do |language|
|
|
11
|
+
%li.howdoc-language{ class: ('howdoc-current' if language[:current]) }
|
|
12
|
+
- if language[:href]
|
|
13
|
+
%a{ href: language[:href], lang: language[:code] }= language[:label]
|
|
14
|
+
- else
|
|
15
|
+
%span{ lang: language[:code] }= language[:label]
|
|
16
|
+
%ul.howdoc-toc
|
|
17
|
+
- previous_group = nil
|
|
18
|
+
- @records.each do |record|
|
|
19
|
+
- group = @config.group_label.call(record)
|
|
20
|
+
- if group && group != previous_group
|
|
21
|
+
%li.howdoc-toc-group= group
|
|
22
|
+
- previous_group = group
|
|
23
|
+
- current = @current && record.filename == @current.filename
|
|
24
|
+
%li.howdoc-toc-entry{ class: ('howdoc-current' if current) }
|
|
25
|
+
%a{ href: "./#{record.filename}", 'aria-current': (current ? 'page' : nil) }= record.heading
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-# Step-by-step guides are read in order, so each one says what comes next.
|
|
2
|
+
-# Written by the same pass as the menu, for the same reason.
|
|
3
|
+
%nav.howdoc-pager{ data: { howdoc_pager: true } }
|
|
4
|
+
- if @previous
|
|
5
|
+
%a.howdoc-pager-link.howdoc-pager-previous{ href: "./#{@previous.filename}", rel: 'prev' }
|
|
6
|
+
%span.howdoc-pager-label= Howdoc::Narrator.phrase(:pager, :previous, locale: @locale)
|
|
7
|
+
%span.howdoc-pager-heading= @previous.heading
|
|
8
|
+
- if @next
|
|
9
|
+
%a.howdoc-pager-link.howdoc-pager-next{ href: "./#{@next.filename}", rel: 'next' }
|
|
10
|
+
%span.howdoc-pager-label= Howdoc::Narrator.phrase(:pager, :next, locale: @locale)
|
|
11
|
+
%span.howdoc-pager-heading= @next.heading
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: howdoc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Priit Tark
|
|
@@ -61,6 +61,7 @@ files:
|
|
|
61
61
|
- lib/howdoc/edition.rb
|
|
62
62
|
- lib/howdoc/minitest.rb
|
|
63
63
|
- lib/howdoc/narrator.rb
|
|
64
|
+
- lib/howdoc/navigation.rb
|
|
64
65
|
- lib/howdoc/recorder.rb
|
|
65
66
|
- lib/howdoc/registry.rb
|
|
66
67
|
- lib/howdoc/screenshot.rb
|
|
@@ -73,6 +74,8 @@ files:
|
|
|
73
74
|
- templates/default/document/html/layout.haml
|
|
74
75
|
- templates/default/document/html/step.haml
|
|
75
76
|
- templates/default/index/html/layout.haml
|
|
77
|
+
- templates/default/shared/html/nav.haml
|
|
78
|
+
- templates/default/shared/html/pager.haml
|
|
76
79
|
homepage: https://github.com/priit/howdoc
|
|
77
80
|
licenses:
|
|
78
81
|
- MIT
|