proscribe 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.md +4 -0
- data/README.md +7 -0
- data/bin/proscribe +5 -0
- data/data/default/Gemfile +5 -0
- data/data/default/Gemfile.lock +43 -0
- data/data/default/Protonfile +14 -0
- data/data/default/_extensions/manual/lib/cli.rb +18 -0
- data/data/default/_extensions/manual/lib/extractor.rb +206 -0
- data/data/default/_extensions/manual/lib/helpers.rb +32 -0
- data/data/default/_extensions/manual/manual.rb +2 -0
- data/data/default/_layouts/_nav.haml +8 -0
- data/data/default/_layouts/default.haml +123 -0
- data/data/default/style.scss +412 -0
- data/data/rack/Gemfile +2 -0
- data/data/rack/config.ru +8 -0
- data/lib/proscribe/cli.rb +45 -0
- data/lib/proscribe/extractor.rb +158 -0
- data/lib/proscribe/helpers.rb +42 -0
- data/lib/proscribe/project.rb +92 -0
- data/lib/proscribe/rack_app.rb +26 -0
- data/lib/proscribe/version.rb +11 -0
- data/lib/proscribe/watcher.rb +63 -0
- data/lib/proscribe.rb +40 -0
- metadata +137 -0
@@ -0,0 +1,412 @@
|
|
1
|
+
$bg: url("data:image/jpeg;charset=utf-8;base64,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");
|
2
|
+
|
3
|
+
@import 'compass/css3';
|
4
|
+
@import 'compass/reset';
|
5
|
+
|
6
|
+
$heading: white;
|
7
|
+
$dark: #456079;
|
8
|
+
$code: mix(#def, white, 50%);
|
9
|
+
$ulite: 'HelveticaNeue-UltraLight', 'Helvetica Neue UltraLight', 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
10
|
+
|
11
|
+
$link: #456 * 1.2;
|
12
|
+
|
13
|
+
// Cross-browser PIE clear fix
|
14
|
+
@mixin clearfix {
|
15
|
+
zoom: 1;
|
16
|
+
&:after { content: 'HelveticaNeue-UltraLight', 'Helvetica Neue UltraLight', 'Helvetica Neue', Arial, Helvetica, sans-serif''; clear: both; display: block; line-height: 0; height: 0; visibility: hidden; zoom: 1; }
|
17
|
+
}
|
18
|
+
|
19
|
+
body {
|
20
|
+
background: $bg; color: #666;
|
21
|
+
font-family: 'lucida grande', sans-serif;
|
22
|
+
font-size: 10.5pt;
|
23
|
+
line-height: 1.6;
|
24
|
+
}
|
25
|
+
|
26
|
+
a { text-decoration: none; color: $link; }
|
27
|
+
a:visited { color: $link * 1.4; }
|
28
|
+
a:hover { color: $link * 0.9; }
|
29
|
+
|
30
|
+
.content {
|
31
|
+
h1 { font-size: 2.5em; }
|
32
|
+
h2 { font-size: 1.2em; }
|
33
|
+
h3 { font-size: 1.1em; }
|
34
|
+
h4 { font-size: 1.2em; }
|
35
|
+
h5 { font-size: 0.9em; }
|
36
|
+
h6 { font-size: 0.8em; }
|
37
|
+
h1, h2, h3, h4, h5, h6 { font-weight: bold; }
|
38
|
+
h1, h2, h3, h4, h5, h6, p, ul, blockquote { margin: 20px 0; }
|
39
|
+
blockquote { padding: 10px; border-left: solid 2px #aaa; }
|
40
|
+
strong { font-weight: bold; }
|
41
|
+
em { font-style: italic; }
|
42
|
+
ul { margin-left: 2em; }
|
43
|
+
ul li { list-style-type: disc; }
|
44
|
+
>:first-child { &, :first-child { margin-top: 0; } }
|
45
|
+
>:last-child { &, :last-child { margin-bottom: 0; } }
|
46
|
+
|
47
|
+
code, pre {
|
48
|
+
font-style: normal;
|
49
|
+
color: #456;
|
50
|
+
text-shadow: 1px 1px 0 rgba(white, 0.7);
|
51
|
+
background: $code; font-family: monaco, monospace; font-size: 0.9em; }
|
52
|
+
|
53
|
+
code {
|
54
|
+
padding: 1px 5px; @include border-radius(2px);
|
55
|
+
font-size: 0.8em; margin: 0 2px;
|
56
|
+
@include box-shadow(1px 1px 0 rgba(black, 0.1)); }
|
57
|
+
|
58
|
+
pre code {
|
59
|
+
font-size: 1em; margin: 0;
|
60
|
+
padding: 0; @include box-shadow(none); }
|
61
|
+
|
62
|
+
pre {
|
63
|
+
overflow: auto;
|
64
|
+
padding: 20px;
|
65
|
+
font-size: 9pt;
|
66
|
+
white-space: pre;
|
67
|
+
@include border-radius(4px);
|
68
|
+
@include box-shadow(1px 1px 0 rgba(black, 0.1), inset 2px 2px 4px rgba(black, 0.1)); }
|
69
|
+
|
70
|
+
span.context {
|
71
|
+
color: #888; font-size: 0.9em; }
|
72
|
+
}
|
73
|
+
|
74
|
+
#top {
|
75
|
+
background: rgba(black, 0.1);
|
76
|
+
padding: 5px;
|
77
|
+
color: #ddd;
|
78
|
+
text-shadow: 1px 1px 0 rgba(black, 0.1);
|
79
|
+
@include clearfix;
|
80
|
+
line-height: 30px;
|
81
|
+
}
|
82
|
+
|
83
|
+
#logo {
|
84
|
+
float: left; width: 200px;
|
85
|
+
padding: 0 10px;
|
86
|
+
color: white; text-decoration: none;
|
87
|
+
font-weight: bold;
|
88
|
+
}
|
89
|
+
|
90
|
+
//
|
91
|
+
// Tabs
|
92
|
+
//
|
93
|
+
#crumbs {
|
94
|
+
& {
|
95
|
+
position: absolute; top: -26px; left: 0;
|
96
|
+
margin: 0; padding: 0; }
|
97
|
+
|
98
|
+
a, strong {
|
99
|
+
display: inline-block;
|
100
|
+
height: 26px;
|
101
|
+
line-height: 26px;
|
102
|
+
font-size: 8pt;
|
103
|
+
padding: 0 45px 0 8px; }
|
104
|
+
|
105
|
+
a {
|
106
|
+
text-decoration: none; color: #ddd;
|
107
|
+
text-shadow: 1px 1px 0 rgba(black, 0.2);
|
108
|
+
background: rgba(black, 0.2); }
|
109
|
+
|
110
|
+
a:hover {
|
111
|
+
color: #ddd;
|
112
|
+
background: rgba(black, 0.3); }
|
113
|
+
|
114
|
+
strong {
|
115
|
+
font-weight: bold;
|
116
|
+
text-shadow: 1px 1px 0 rgba(white, 0.2);
|
117
|
+
background: $heading; color: #666; }
|
118
|
+
|
119
|
+
span.gt {
|
120
|
+
display: none; }
|
121
|
+
}
|
122
|
+
|
123
|
+
#area {
|
124
|
+
padding-left: 200px;
|
125
|
+
width: 90%;
|
126
|
+
max-width: 1100px;
|
127
|
+
min-width: 800px;
|
128
|
+
|
129
|
+
@include box-sizing(border-box);
|
130
|
+
margin: 0 auto;
|
131
|
+
}
|
132
|
+
|
133
|
+
$pad: 40px;
|
134
|
+
|
135
|
+
#content {
|
136
|
+
@include border-top-radius(2px);
|
137
|
+
background: white; padding: 40px;
|
138
|
+
position: relative;
|
139
|
+
@include box-sizing(border-box);
|
140
|
+
@include clearfix;
|
141
|
+
@include box-shadow(
|
142
|
+
0 3px 4px rgba(black, 0.1));
|
143
|
+
}
|
144
|
+
|
145
|
+
//
|
146
|
+
// Top heading
|
147
|
+
//
|
148
|
+
#content hgroup {
|
149
|
+
background: $heading;
|
150
|
+
margin: $pad * -1; margin-bottom: 0;
|
151
|
+
padding: 40px $pad;
|
152
|
+
|
153
|
+
h1, p {
|
154
|
+
margin: 0; padding: 0; }
|
155
|
+
|
156
|
+
h1 {
|
157
|
+
font-size: 30pt; font-weight: normal;
|
158
|
+
color: #aaa;
|
159
|
+
text-shadow: 2px 2px 0 rgba(black, 0.04);
|
160
|
+
font-family: $ulite;
|
161
|
+
line-height: 40pt; }
|
162
|
+
|
163
|
+
h5 {
|
164
|
+
color: #abc;
|
165
|
+
font-size: 1.5em; }
|
166
|
+
|
167
|
+
p.type {
|
168
|
+
line-height: 40pt;
|
169
|
+
padding: 0 30px;
|
170
|
+
margin: 0 20px 0 -10px;
|
171
|
+
background: rgba(black, 0.1);
|
172
|
+
@include border-radius(4px);
|
173
|
+
float: left; }
|
174
|
+
}
|
175
|
+
|
176
|
+
#content>div {
|
177
|
+
float: left;
|
178
|
+
width: 100%;
|
179
|
+
@include box-sizing(border-box);
|
180
|
+
margin-right: -200px; min-height: 500px;
|
181
|
+
}
|
182
|
+
|
183
|
+
.content {
|
184
|
+
line-height: 1.7;
|
185
|
+
|
186
|
+
>:first-child { margin-top: 0; }
|
187
|
+
>p:first-child, p.brief {
|
188
|
+
font-family: georgia, serif;
|
189
|
+
font-style: italic;
|
190
|
+
margin-bottom: 25px;
|
191
|
+
font-size: 1.2em; color: #abc; line-height: 1.7; }
|
192
|
+
|
193
|
+
>p:first-child {
|
194
|
+
margin-top: -40px;
|
195
|
+
}
|
196
|
+
|
197
|
+
>h2, >h3 {
|
198
|
+
& + pre {
|
199
|
+
margin-top: 20px !important; }
|
200
|
+
|
201
|
+
font-size: 2em;
|
202
|
+
font-weight: normal;
|
203
|
+
font-family: $ulite;
|
204
|
+
|
205
|
+
text-shadow: 1px 1px 0 #eaeff3 * 1.1;
|
206
|
+
border-left: 0; border-right: 0;
|
207
|
+
padding: 5px $pad;
|
208
|
+
padding-top: 30px;
|
209
|
+
margin: 40px $pad*-1 -10px $pad*-1;
|
210
|
+
color: #aaa;
|
211
|
+
|
212
|
+
border-top: dotted 1px #eaeff3 * 0.95;
|
213
|
+
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
#nav {
|
218
|
+
& {
|
219
|
+
float: left;
|
220
|
+
width: 200px;
|
221
|
+
overflow: hidden;
|
222
|
+
position: relative; top: -5px; left: $pad * -1;
|
223
|
+
margin-left: -100%; }
|
224
|
+
|
225
|
+
& {
|
226
|
+
font-size: 9pt; }
|
227
|
+
|
228
|
+
a {
|
229
|
+
position: relative;
|
230
|
+
line-height: 24px;
|
231
|
+
@include border-left-radius(4px);
|
232
|
+
color: #fff; text-shadow: 1px 1px 0 rgba(black, 0.2);
|
233
|
+
padding: 1px 5px; display: block; text-decoration: none; }
|
234
|
+
|
235
|
+
a:hover {
|
236
|
+
background: rgba($dark, 0.1); }
|
237
|
+
|
238
|
+
nav.parents a.active,
|
239
|
+
a.active {
|
240
|
+
background: rgba(black, 0.1); color: #fff; font-weight: bold;
|
241
|
+
@include box-shadow(1px 1px 0 rgba(white, 0.2));
|
242
|
+
text-shadow: 1px 1px 0 rgba(black, 0.2); }
|
243
|
+
|
244
|
+
$indent: 10px;
|
245
|
+
ul a { padding-left: $indent * 1; }
|
246
|
+
ul ul a { padding-left: $indent * 2; }
|
247
|
+
ul ul ul a { padding-left: $indent * 3; }
|
248
|
+
ul ul ul ul a { padding-left: $indent * 4; }
|
249
|
+
|
250
|
+
ul + ul {
|
251
|
+
margin-top: 10px;
|
252
|
+
border-top: solid 1px #bbb; padding-top: 10px; }
|
253
|
+
|
254
|
+
nav {
|
255
|
+
padding: 10px 0; }
|
256
|
+
|
257
|
+
// Moar
|
258
|
+
a.more::after {
|
259
|
+
display: block; content: '›';
|
260
|
+
position: relative; top: -2px;
|
261
|
+
font-size: 1.4em;
|
262
|
+
padding-right: 10px;
|
263
|
+
float: right; }
|
264
|
+
|
265
|
+
// Type names
|
266
|
+
a em {
|
267
|
+
font-size: 0.8em;
|
268
|
+
line-height: 16px;
|
269
|
+
font-weight: normal;
|
270
|
+
opacity: 0.5;
|
271
|
+
float: right; }
|
272
|
+
|
273
|
+
nav a em {
|
274
|
+
display: none; }
|
275
|
+
|
276
|
+
nav.parents a em {
|
277
|
+
opacity: 0.5;
|
278
|
+
position: relative; top: 4px;
|
279
|
+
display: block;
|
280
|
+
padding: 0 8px;
|
281
|
+
@include border-radius(10px);
|
282
|
+
background: rgba(black, 0.3); }
|
283
|
+
|
284
|
+
h4 {
|
285
|
+
font-size: 8pt;
|
286
|
+
padding: 2px 5px;
|
287
|
+
@include border-left-radius(2px);
|
288
|
+
margin-bottom: 10px;
|
289
|
+
border-bottom: solid 1px rgba(black, 0.1);
|
290
|
+
}
|
291
|
+
|
292
|
+
// Parents
|
293
|
+
nav.parents {
|
294
|
+
a {
|
295
|
+
margin-bottom: 1px;
|
296
|
+
background: rgba(white, 0.3); }
|
297
|
+
|
298
|
+
span.back {
|
299
|
+
display: inline-block;
|
300
|
+
text-align: center;
|
301
|
+
font-size: 1.3em;
|
302
|
+
width: 20px; }
|
303
|
+
|
304
|
+
a.active {
|
305
|
+
padding-left: 32px; }
|
306
|
+
}
|
307
|
+
}
|
308
|
+
|
309
|
+
//
|
310
|
+
// Links
|
311
|
+
//
|
312
|
+
ul.section {
|
313
|
+
margin-top: 30px !important;
|
314
|
+
font-size: 0.9em;
|
315
|
+
|
316
|
+
&, li {
|
317
|
+
margin: 0; padding: 0; display: block;
|
318
|
+
list-style-type: none; }
|
319
|
+
|
320
|
+
li {
|
321
|
+
margin: 0 -40px;
|
322
|
+
padding: 3px 40px; }
|
323
|
+
|
324
|
+
li:nth-child(odd) {
|
325
|
+
background: #eee; }
|
326
|
+
|
327
|
+
li:nth-child(even) {
|
328
|
+
background: #fafafa; }
|
329
|
+
|
330
|
+
li a {
|
331
|
+
display: inline-block; width: 200px;
|
332
|
+
font-size: 1em;
|
333
|
+
font-weight: bold; }
|
334
|
+
}
|
335
|
+
|
336
|
+
//
|
337
|
+
// Yeah
|
338
|
+
//
|
339
|
+
|
340
|
+
pre.has-caption {
|
341
|
+
position: relative;
|
342
|
+
|
343
|
+
h5 {
|
344
|
+
margin: 0; padding: 0;
|
345
|
+
display: block;
|
346
|
+
padding: 0 10px;
|
347
|
+
color: #888; text-shadow: 1px 1px 0 rgba(white, 0.6);
|
348
|
+
|
349
|
+
font-size: 8pt;
|
350
|
+
line-height: 18pt;
|
351
|
+
font-weight: normal;
|
352
|
+
font-family: sans-serif;
|
353
|
+
background: rgba(black, 0.1);
|
354
|
+
@include border-bottom-left-radius(4px);
|
355
|
+
|
356
|
+
position: absolute;
|
357
|
+
top: 0;
|
358
|
+
right: 0;
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
362
|
+
pre.terminal {
|
363
|
+
background: #222;
|
364
|
+
|
365
|
+
code {
|
366
|
+
color: #ccc;
|
367
|
+
text-shadow: 1px 1px 0 rgba(black, 0.3);
|
368
|
+
background: transparent; }
|
369
|
+
|
370
|
+
strong {
|
371
|
+
font-size: 1.1em;
|
372
|
+
color: #8d8; font-weight: normal; }
|
373
|
+
|
374
|
+
strong em {
|
375
|
+
font-style: normal;
|
376
|
+
color: #8d8 * 0.5; }
|
377
|
+
}
|
378
|
+
|
379
|
+
//
|
380
|
+
// Prettify
|
381
|
+
//
|
382
|
+
|
383
|
+
/* Pretty printing styles. Used with prettify.js. */
|
384
|
+
|
385
|
+
.str { color: #080; }
|
386
|
+
.kwd { color: #008; }
|
387
|
+
.com { color: #607077; background: rgba(black, 0.05); padding: 1px 3px; @include border-radius(2px); @include box-shadow(1px 1px 0 rgba(black, 0.1), -1px -1px 0 rgba(white, 0.1)); }
|
388
|
+
.typ { color: #606; }
|
389
|
+
.lit { color: #066; }
|
390
|
+
.pun { color: #660; }
|
391
|
+
.pln { color: #000; }
|
392
|
+
.tag { color: #008; }
|
393
|
+
.atn { color: #606; }
|
394
|
+
.atv { color: #080; }
|
395
|
+
.dec { color: #606; }
|
396
|
+
|
397
|
+
/* Specify class=linenums on a pre to get line numbering */
|
398
|
+
ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
|
399
|
+
li.L0,
|
400
|
+
li.L1,
|
401
|
+
li.L2,
|
402
|
+
li.L3,
|
403
|
+
li.L5,
|
404
|
+
li.L6,
|
405
|
+
li.L7,
|
406
|
+
li.L8 { list-style-type: none }
|
407
|
+
/* Alternate shading for lines */
|
408
|
+
li.L1,
|
409
|
+
li.L3,
|
410
|
+
li.L5,
|
411
|
+
li.L7,
|
412
|
+
li.L9 { background: #eee }
|
data/data/rack/Gemfile
ADDED
data/data/rack/config.ru
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Class: CLI (ProScribe)
|
2
|
+
# The CLI runner.
|
3
|
+
#
|
4
|
+
class ProScribe::CLI < Shake
|
5
|
+
include Shake::Defaults
|
6
|
+
extend ProScribe::Helpers
|
7
|
+
|
8
|
+
task(:build) do
|
9
|
+
project.make
|
10
|
+
pass project.dir if ARGV.delete('-d') || ARGV.delete('--debug')
|
11
|
+
|
12
|
+
Dir.chdir(project.dir) {
|
13
|
+
system "proton build"
|
14
|
+
}
|
15
|
+
|
16
|
+
copy_files project.dir('_output'), project.root(project.config.output)
|
17
|
+
end
|
18
|
+
|
19
|
+
task.description = "Builds the project files"
|
20
|
+
|
21
|
+
task(:start) do
|
22
|
+
project.make
|
23
|
+
|
24
|
+
w = ProScribe::Watcher.new(project) { |path, file| status "Updated #{file}" }
|
25
|
+
|
26
|
+
server = Thread.new {
|
27
|
+
Dir.chdir(project.dir) {
|
28
|
+
status "Starting Proton server"
|
29
|
+
system "proton start", *ARGV[1..-1]
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
w.join
|
34
|
+
server.join
|
35
|
+
end
|
36
|
+
task.description = "Starts a preview server on localhost"
|
37
|
+
|
38
|
+
task(:rack) do
|
39
|
+
dir = Dir.pwd
|
40
|
+
project
|
41
|
+
copy_files ProScribe.root('data/rack'), dir
|
42
|
+
end
|
43
|
+
task.description = "Makes a project Rack-compatible"
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module ProScribe
|
7
|
+
# Extracts comments from list of files.
|
8
|
+
# Gets the ones with comment blocks starting with `[...]`
|
9
|
+
#
|
10
|
+
# == Common usage
|
11
|
+
#
|
12
|
+
# ex = Extractor.new(Dir['./**/*.rb'])
|
13
|
+
# ex.blocks
|
14
|
+
#
|
15
|
+
# ex.blocks.map! { |b| b.file = "file: #{b.file}" }
|
16
|
+
#
|
17
|
+
# ex.write!('manual/') # Writes to manual/
|
18
|
+
#
|
19
|
+
class Extractor
|
20
|
+
def initialize(files, options={})
|
21
|
+
@files = files
|
22
|
+
end
|
23
|
+
|
24
|
+
def write!(output_path = '.', &blk)
|
25
|
+
blocks.each { |block|
|
26
|
+
path = File.join(output_path, block.file)
|
27
|
+
FileUtils.mkdir_p File.dirname(path)
|
28
|
+
File.open(path, 'w') { |f| f.write block.body }
|
29
|
+
yield block if block_given?
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns an array of Extractor::Blocks.
|
34
|
+
def blocks
|
35
|
+
@blocks ||= begin
|
36
|
+
@files.map { |file|
|
37
|
+
if File.file?(file)
|
38
|
+
input = File.read(file)
|
39
|
+
get_blocks input
|
40
|
+
end
|
41
|
+
}.compact.flatten
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
# Returns blocks that match a blah.
|
47
|
+
def get_blocks(str)
|
48
|
+
arr = get_comment_blocks(str)
|
49
|
+
arr.map { |block|
|
50
|
+
re = /^([A-Za-z ]*?): (.*?)(?: \((.*?)\))?$/
|
51
|
+
|
52
|
+
if block.last =~ re
|
53
|
+
Extractor::Block.new \
|
54
|
+
:type => $1,
|
55
|
+
:title => $2,
|
56
|
+
:parent => $3,
|
57
|
+
:body => (block[0..-2].join("\n") + "\n")
|
58
|
+
elsif block.first =~ re
|
59
|
+
Extractor::Block.new \
|
60
|
+
:type => $1,
|
61
|
+
:title => $2,
|
62
|
+
:parent => $3,
|
63
|
+
:body => (block[1..-1].join("\n") + "\n")
|
64
|
+
end
|
65
|
+
}.compact
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns contiguous comment blocks.
|
69
|
+
def get_comment_blocks(str)
|
70
|
+
chunks = Array.new
|
71
|
+
i = 0
|
72
|
+
|
73
|
+
str.split("\n").each { |s|
|
74
|
+
if s =~ /^\s*(?:\/\/\/?|##?) ?(.*)$/
|
75
|
+
chunks[i] ||= Array.new
|
76
|
+
chunks[i] << $1
|
77
|
+
else
|
78
|
+
i += 1 if chunks[i]
|
79
|
+
end
|
80
|
+
}
|
81
|
+
|
82
|
+
chunks
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class Extractor::Block
|
87
|
+
attr_accessor :body
|
88
|
+
attr_accessor :file
|
89
|
+
|
90
|
+
def initialize(options)
|
91
|
+
title = options[:title]
|
92
|
+
parent = options[:parent]
|
93
|
+
body = options[:body]
|
94
|
+
type = options[:type].downcase
|
95
|
+
|
96
|
+
file = to_filename(title, parent)
|
97
|
+
brief, *body = body.split("\n\n")
|
98
|
+
body = "#{body.join("\n\n")}"
|
99
|
+
|
100
|
+
heading = "title: #{title}\npage_type: #{type}\nbrief: #{brief}\n"
|
101
|
+
heading += "--\n"
|
102
|
+
|
103
|
+
@file = file
|
104
|
+
body = Tilt.new(".md") { body }.render
|
105
|
+
body = fix_links(body, from: file)
|
106
|
+
@body = heading + body
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
def fix_links(str, options={})
|
111
|
+
from = ("/" + options[:from].to_s).squeeze('/')
|
112
|
+
depth = from.to_s.count('/')
|
113
|
+
indent = (depth > 1 ? '../'*(depth-1) : './')[0..-2]
|
114
|
+
|
115
|
+
# First pass, {Helpers::content_for} to become links
|
116
|
+
str = str.gsub(/{([^}]*?)}/) { |s|
|
117
|
+
s = s.gsub(/{|}/, '')
|
118
|
+
|
119
|
+
m = s.match(/^(.*?)[:\.]+([A-Za-z_\(\)\!\?]+)$/)
|
120
|
+
if m
|
121
|
+
name, context = $2, $1
|
122
|
+
else
|
123
|
+
name, context = s, nil
|
124
|
+
end
|
125
|
+
|
126
|
+
s = "<a href='/#{to_filename(s, '', :ext => '.html')}'>#{name}</a>"
|
127
|
+
s += " <span class='context'>(#{context})</span>" if context
|
128
|
+
s
|
129
|
+
}
|
130
|
+
|
131
|
+
# Second pass, relativize
|
132
|
+
re = /href=['"](\/(?:.*?))['"]/
|
133
|
+
str.gsub(re) { |s|
|
134
|
+
url = s.match(re) && $1
|
135
|
+
url = "#{indent}/#{url}".squeeze('/')
|
136
|
+
"href=#{url.inspect}"
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
def to_filename(title, parent='', options={})
|
141
|
+
extension = options[:ext] || '.erb'
|
142
|
+
pathify = lambda { |s|
|
143
|
+
s.to_s.scan(/[A-Za-z0-9_\!\?]+/).map { |chunk|
|
144
|
+
chunk = chunk.gsub('?', '_question')
|
145
|
+
chunk = chunk.gsub('!', '_bang')
|
146
|
+
|
147
|
+
if chunk[0].upcase == chunk[0]
|
148
|
+
chunk
|
149
|
+
else
|
150
|
+
"#{chunk}_"
|
151
|
+
end
|
152
|
+
}.join("/").downcase
|
153
|
+
}
|
154
|
+
|
155
|
+
(pathify["#{parent}/#{title}"] + extension)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Module: Helpers (ProScribe)
|
2
|
+
# Useful functions for the CLI runner.
|
3
|
+
#
|
4
|
+
module ProScribe
|
5
|
+
module Helpers
|
6
|
+
def project
|
7
|
+
@project ||= begin
|
8
|
+
config = find_config_file
|
9
|
+
Dir.chdir(File.dirname(config)) if config
|
10
|
+
Project.new(config) if config
|
11
|
+
end
|
12
|
+
|
13
|
+
@project || pass(no_project)
|
14
|
+
end
|
15
|
+
|
16
|
+
def no_project
|
17
|
+
"Error: no Scribefile file found."
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_config_file
|
21
|
+
%w(Scribefile).inject(nil) { |a, fname| a ||= find_in_project(fname) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def status(msg)
|
25
|
+
puts " * #{msg}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def copy_files(from, to, options={})
|
29
|
+
exceptions = options[:except] || []
|
30
|
+
|
31
|
+
Dir["#{from}/**/*"].each do |f|
|
32
|
+
next unless File.file?(f)
|
33
|
+
next if exceptions.include?(File.basename(f))
|
34
|
+
|
35
|
+
target = File.join(to, f.gsub(from, ''))
|
36
|
+
|
37
|
+
FileUtils.mkdir_p File.dirname(target)
|
38
|
+
FileUtils.cp f, target
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|