steppe 0.1.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.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
9
+
10
+ desc "Build documentation website from README"
11
+ task :docs, [:readme_path, :output_dir] do |t, args|
12
+ require_relative 'lib/docs_builder'
13
+
14
+ readme_path = args[:readme_path] || 'README.md'
15
+ output_dir = args[:output_dir] || 'docs'
16
+
17
+ builder = DocsBuilder.new(
18
+ readme_path: readme_path,
19
+ output_dir: output_dir
20
+ )
21
+
22
+ builder.build
23
+ end
data/docs/README.md ADDED
@@ -0,0 +1,3 @@
1
+ ## Generate docs
2
+
3
+ Run `bundle exec rake docs` to turn the main README.md into `docs/index.html`
data/docs/styles.css ADDED
@@ -0,0 +1,527 @@
1
+ /* Reset and Base Styles */
2
+ * {
3
+ margin: 0;
4
+ padding: 0;
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ :root {
9
+ --primary-color: #2563eb;
10
+ --primary-dark: #1e40af;
11
+ --secondary-color: #64748b;
12
+ --bg-color: #f8fafc;
13
+ --sidebar-bg: #1e293b;
14
+ --sidebar-text: #cbd5e1;
15
+ --sidebar-hover: #334155;
16
+ --content-bg: #ffffff;
17
+ --text-color: #1e293b;
18
+ --text-light: #64748b;
19
+ --border-color: #e2e8f0;
20
+ --code-bg: #f1f5f9;
21
+ --code-border: #cbd5e1;
22
+ --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
23
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
24
+ }
25
+
26
+ html {
27
+ scroll-behavior: smooth;
28
+ }
29
+
30
+ body {
31
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
32
+ line-height: 1.6;
33
+ color: var(--text-color);
34
+ background-color: var(--bg-color);
35
+ padding-top: 60px;
36
+ }
37
+
38
+ /* Top Menu Bar */
39
+ .top-menu {
40
+ position: fixed;
41
+ top: 0;
42
+ left: 0;
43
+ right: 0;
44
+ height: 60px;
45
+ background-color: var(--content-bg);
46
+ border-bottom: 1px solid var(--border-color);
47
+ box-shadow: var(--shadow);
48
+ z-index: 1000;
49
+ }
50
+
51
+ .top-menu-content {
52
+ max-width: 100%;
53
+ height: 100%;
54
+ padding: 0 2rem;
55
+ display: flex;
56
+ justify-content: space-between;
57
+ align-items: center;
58
+ }
59
+
60
+ .top-menu-brand {
61
+ display: flex;
62
+ align-items: baseline;
63
+ gap: 0.75rem;
64
+ }
65
+
66
+ .brand-name {
67
+ font-size: 1.5rem;
68
+ font-weight: 700;
69
+ color: var(--text-color);
70
+ }
71
+
72
+ .brand-tagline {
73
+ font-size: 0.875rem;
74
+ color: var(--text-light);
75
+ font-weight: 400;
76
+ }
77
+
78
+ .top-menu .github-link {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 0.5rem;
82
+ padding: 0.5rem 1rem;
83
+ background-color: var(--text-color);
84
+ color: #ffffff;
85
+ border-radius: 6px;
86
+ text-decoration: none;
87
+ font-weight: 600;
88
+ font-size: 0.875rem;
89
+ transition: all 0.2s ease;
90
+ }
91
+
92
+ .top-menu .github-link:hover {
93
+ background-color: #000000;
94
+ text-decoration: none;
95
+ }
96
+
97
+ .top-menu .github-link svg {
98
+ width: 20px;
99
+ height: 20px;
100
+ }
101
+
102
+ /* Layout */
103
+ .container {
104
+ display: flex;
105
+ min-height: calc(100vh - 60px);
106
+ }
107
+
108
+ /* Sidebar */
109
+ .sidebar {
110
+ width: 280px;
111
+ background-color: var(--sidebar-bg);
112
+ color: var(--sidebar-text);
113
+ padding: 2rem 0;
114
+ position: fixed;
115
+ top: 60px;
116
+ height: calc(100vh - 60px);
117
+ overflow-y: auto;
118
+ box-shadow: var(--shadow-lg);
119
+ }
120
+
121
+ .sidebar::-webkit-scrollbar {
122
+ width: 8px;
123
+ }
124
+
125
+ .sidebar::-webkit-scrollbar-track {
126
+ background: var(--sidebar-bg);
127
+ }
128
+
129
+ .sidebar::-webkit-scrollbar-thumb {
130
+ background: var(--sidebar-hover);
131
+ border-radius: 4px;
132
+ }
133
+
134
+ .logo {
135
+ padding: 0 1.5rem 1.5rem;
136
+ border-bottom: 1px solid var(--sidebar-hover);
137
+ margin-bottom: 1.5rem;
138
+ }
139
+
140
+ .logo h2 {
141
+ font-size: 1.75rem;
142
+ color: #ffffff;
143
+ margin-bottom: 0.25rem;
144
+ font-weight: 700;
145
+ }
146
+
147
+ .logo .tagline {
148
+ font-size: 0.875rem;
149
+ color: var(--sidebar-text);
150
+ font-weight: 400;
151
+ }
152
+
153
+ .nav-menu {
154
+ list-style: none;
155
+ padding-left: 0;
156
+ }
157
+
158
+ .nav-menu li {
159
+ margin: 0;
160
+ }
161
+
162
+ .nav-menu a {
163
+ display: block;
164
+ padding: 0.625rem 1.5rem;
165
+ color: var(--sidebar-text);
166
+ text-decoration: none;
167
+ transition: all 0.2s ease;
168
+ font-size: 0.9375rem;
169
+ }
170
+
171
+ .nav-menu li:not(.nav-submenu) > a {
172
+ font-weight: 600;
173
+ margin-top: 0.5rem;
174
+ }
175
+
176
+ .nav-submenu a {
177
+ padding-left: 2.5rem;
178
+ font-size: 0.875rem;
179
+ color: var(--sidebar-text);
180
+ opacity: 0.9;
181
+ }
182
+
183
+ .nav-menu a:hover {
184
+ background-color: var(--sidebar-hover);
185
+ color: #ffffff;
186
+ }
187
+
188
+ .nav-menu a.active {
189
+ background-color: var(--primary-color);
190
+ color: #ffffff;
191
+ border-left: 3px solid #ffffff;
192
+ padding-left: calc(1.5rem - 3px);
193
+ }
194
+
195
+ .nav-submenu a.active {
196
+ padding-left: calc(2.5rem - 3px);
197
+ }
198
+
199
+ /* Accordion Menus */
200
+ .nav-accordion {
201
+ position: relative;
202
+ }
203
+
204
+ .accordion-toggle {
205
+ display: flex;
206
+ justify-content: space-between;
207
+ align-items: center;
208
+ cursor: pointer;
209
+ }
210
+
211
+ .accordion-icon {
212
+ font-size: 0.75rem;
213
+ transition: transform 0.2s ease;
214
+ margin-left: 0.5rem;
215
+ }
216
+
217
+ .nav-accordion.expanded .accordion-icon {
218
+ transform: rotate(-180deg);
219
+ }
220
+
221
+ .accordion-content {
222
+ list-style: none;
223
+ padding-left: 0;
224
+ max-height: 0;
225
+ overflow: hidden;
226
+ transition: max-height 0.3s ease;
227
+ }
228
+
229
+ .nav-accordion.expanded .accordion-content {
230
+ max-height: 500px;
231
+ }
232
+
233
+ .nav-h4 a {
234
+ padding-left: 3.5rem;
235
+ font-size: 0.8125rem;
236
+ color: var(--sidebar-text);
237
+ opacity: 0.85;
238
+ }
239
+
240
+ .nav-h4 a.active {
241
+ padding-left: calc(3.5rem - 3px);
242
+ }
243
+
244
+ /* Main Content */
245
+ .content {
246
+ flex: 1;
247
+ margin-left: 280px;
248
+ padding: 3rem;
249
+ max-width: 1200px;
250
+ }
251
+
252
+ /* Page Header */
253
+ .page-header {
254
+ margin-bottom: 3rem;
255
+ padding-bottom: 2rem;
256
+ border-bottom: 2px solid var(--border-color);
257
+ }
258
+
259
+ .page-header h1 {
260
+ font-size: 3rem;
261
+ font-weight: 800;
262
+ color: var(--text-color);
263
+ margin-bottom: 0.5rem;
264
+ letter-spacing: -0.025em;
265
+ }
266
+
267
+ .page-header .subtitle {
268
+ font-size: 1.25rem;
269
+ color: var(--text-light);
270
+ font-weight: 400;
271
+ }
272
+
273
+ /* Sections */
274
+ .section {
275
+ margin-bottom: 4rem;
276
+ }
277
+
278
+ .section h2 {
279
+ font-size: 2rem;
280
+ font-weight: 700;
281
+ color: var(--text-color);
282
+ margin-bottom: 1.5rem;
283
+ padding-bottom: 0.5rem;
284
+ border-bottom: 2px solid var(--primary-color);
285
+ }
286
+
287
+ .subsection {
288
+ margin-bottom: 2.5rem;
289
+ background-color: var(--content-bg);
290
+ padding: 2rem;
291
+ border-radius: 8px;
292
+ box-shadow: var(--shadow);
293
+ }
294
+
295
+ .subsection h3 {
296
+ font-size: 1.5rem;
297
+ font-weight: 600;
298
+ color: var(--text-color);
299
+ margin-bottom: 1rem;
300
+ }
301
+
302
+ .subsection h4 {
303
+ font-size: 1.25rem;
304
+ font-weight: 600;
305
+ color: var(--text-color);
306
+ margin: 1.5rem 0 1rem;
307
+ }
308
+
309
+ /* Typography */
310
+ p {
311
+ margin-bottom: 1rem;
312
+ line-height: 1.75;
313
+ }
314
+
315
+ a {
316
+ color: var(--primary-color);
317
+ text-decoration: none;
318
+ }
319
+
320
+ a:hover {
321
+ color: var(--primary-dark);
322
+ text-decoration: underline;
323
+ }
324
+
325
+ strong {
326
+ font-weight: 600;
327
+ color: var(--text-color);
328
+ }
329
+
330
+ /* Lists */
331
+ ul, ol {
332
+ margin-bottom: 1rem;
333
+ padding-left: 1.5rem;
334
+ }
335
+
336
+ li {
337
+ margin-bottom: 0.5rem;
338
+ }
339
+
340
+ .feature-list {
341
+ list-style: none;
342
+ padding-left: 0;
343
+ }
344
+
345
+ .feature-list li {
346
+ padding-left: 1.5rem;
347
+ position: relative;
348
+ margin-bottom: 0.75rem;
349
+ }
350
+
351
+ .feature-list li::before {
352
+ content: "→";
353
+ position: absolute;
354
+ left: 0;
355
+ color: var(--primary-color);
356
+ font-weight: bold;
357
+ }
358
+
359
+ /* Code Blocks */
360
+ code {
361
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
362
+ font-size: 0.875em;
363
+ background-color: var(--code-bg);
364
+ padding: 0.2em 0.4em;
365
+ border-radius: 3px;
366
+ border: 1px solid var(--code-border);
367
+ }
368
+
369
+ pre {
370
+ margin: 1.5rem 0;
371
+ padding: 0;
372
+ overflow-x: auto;
373
+ border-radius: 6px;
374
+ box-shadow: var(--shadow);
375
+ background-color: #282c34;
376
+ }
377
+
378
+ pre code {
379
+ display: block;
380
+ padding: 1.25rem;
381
+ background-color: transparent;
382
+ color: inherit;
383
+ border: none;
384
+ border-radius: 6px;
385
+ line-height: 1.6;
386
+ overflow-x: auto;
387
+ }
388
+
389
+ pre code::-webkit-scrollbar {
390
+ height: 8px;
391
+ }
392
+
393
+ pre code::-webkit-scrollbar-track {
394
+ background: var(--sidebar-hover);
395
+ border-radius: 4px;
396
+ }
397
+
398
+ pre code::-webkit-scrollbar-thumb {
399
+ background: var(--sidebar-text);
400
+ border-radius: 4px;
401
+ }
402
+
403
+ /* Images */
404
+ .image-container {
405
+ margin: 2rem 0;
406
+ text-align: center;
407
+ }
408
+
409
+ .image-container img {
410
+ max-width: 100%;
411
+ height: auto;
412
+ }
413
+
414
+ .image-container .caption {
415
+ margin-top: 0.75rem;
416
+ font-size: 0.875rem;
417
+ color: var(--text-light);
418
+ font-style: italic;
419
+ }
420
+
421
+ /* Responsive Design */
422
+ @media (max-width: 1024px) {
423
+ .sidebar {
424
+ width: 240px;
425
+ }
426
+
427
+ .content {
428
+ margin-left: 240px;
429
+ padding: 2rem;
430
+ }
431
+ }
432
+
433
+ @media (max-width: 768px) {
434
+ .top-menu-content {
435
+ padding: 0 1rem;
436
+ }
437
+
438
+ .brand-tagline {
439
+ display: none;
440
+ }
441
+
442
+ .top-menu .github-link span {
443
+ display: none;
444
+ }
445
+
446
+ .top-menu .github-link {
447
+ padding: 0.5rem;
448
+ }
449
+
450
+ .sidebar {
451
+ position: relative;
452
+ top: 0;
453
+ width: 100%;
454
+ height: auto;
455
+ border-right: none;
456
+ border-bottom: 1px solid var(--sidebar-hover);
457
+ }
458
+
459
+ .content {
460
+ margin-left: 0;
461
+ padding: 1.5rem;
462
+ }
463
+
464
+ .page-header h1 {
465
+ font-size: 2rem;
466
+ }
467
+
468
+ .page-header .subtitle {
469
+ font-size: 1rem;
470
+ }
471
+
472
+ .section h2 {
473
+ font-size: 1.5rem;
474
+ }
475
+
476
+ .subsection {
477
+ padding: 1.5rem;
478
+ }
479
+
480
+ .subsection h3 {
481
+ font-size: 1.25rem;
482
+ }
483
+
484
+ pre code {
485
+ padding: 1rem;
486
+ font-size: 0.8125rem;
487
+ }
488
+ }
489
+
490
+ /* Smooth Scrolling and Anchor Offset */
491
+ section {
492
+ scroll-margin-top: 5rem;
493
+ }
494
+
495
+ article {
496
+ scroll-margin-top: 5rem;
497
+ }
498
+
499
+ /* Print Styles */
500
+ @media print {
501
+ .top-menu {
502
+ display: none;
503
+ }
504
+
505
+ body {
506
+ padding-top: 0;
507
+ }
508
+
509
+ .sidebar {
510
+ display: none;
511
+ }
512
+
513
+ .content {
514
+ margin-left: 0;
515
+ max-width: 100%;
516
+ }
517
+
518
+ .subsection {
519
+ box-shadow: none;
520
+ border: 1px solid var(--border-color);
521
+ }
522
+
523
+ pre code {
524
+ background-color: var(--code-bg);
525
+ color: var(--text-color);
526
+ }
527
+ }
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # From the root, run with:
4
+ # bundle exec rackup examples/hanami.ru
5
+ #
6
+ require 'bundler'
7
+ Bundler.setup(:examples, :sinatra)
8
+
9
+ require 'hanami/router'
10
+ require 'rack/cors'
11
+ require_relative './service'
12
+
13
+ app = Service.route_with(Hanami::Router.new)
14
+ # app = Hanami::Router.new do
15
+ # scope '/api' do
16
+ # Service.route_with(self)
17
+ # end
18
+ # end
19
+
20
+ # Allowing all origins
21
+ # to make Swagger UI work
22
+ use Rack::Cors do
23
+ allow do
24
+ origins '*'
25
+ resource '*', headers: :any, methods: :any
26
+ end
27
+ end
28
+
29
+ run app