needle 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/manual-html/chapter-1.html +138 -78
- data/doc/manual-html/chapter-2.html +180 -99
- data/doc/manual-html/chapter-3.html +111 -75
- data/doc/manual-html/chapter-4.html +80 -48
- data/doc/manual-html/chapter-5.html +106 -56
- data/doc/manual-html/chapter-6.html +82 -34
- data/doc/manual-html/chapter-7.html +74 -38
- data/doc/manual-html/chapter-8.html +70 -41
- data/doc/manual-html/chapter-9.html +88 -63
- data/doc/manual-html/index.html +6 -6
- data/doc/manual-html/needle.png +0 -0
- data/doc/manual-html/{manual.css → stylesheets/manual.css} +83 -10
- data/doc/manual-html/stylesheets/ruby.css +17 -0
- data/doc/manual/chapter.erb +20 -0
- data/doc/manual/img/Needle.ai +0 -0
- data/doc/manual/img/needle.png +0 -0
- data/doc/manual/manual.rb +80 -5
- data/doc/manual/manual.yml +3 -3
- data/doc/manual/page.erb +1 -1
- data/doc/manual/parts/01_use_cases.txt +70 -70
- data/doc/manual/parts/02_creating.txt +19 -19
- data/doc/manual/parts/02_namespaces.txt +29 -29
- data/doc/manual/parts/02_services.txt +40 -41
- data/doc/manual/parts/03_conventional.txt +20 -20
- data/doc/manual/parts/03_locator.txt +44 -44
- data/doc/manual/parts/04_overview.txt +1 -1
- data/doc/manual/parts/04_setup.txt +32 -32
- data/doc/manual/parts/customizing_contexts.txt +14 -14
- data/doc/manual/parts/customizing_interceptors.txt +25 -25
- data/doc/manual/parts/customizing_namespaces.txt +12 -12
- data/doc/manual/parts/interceptors_attaching.txt +29 -30
- data/doc/manual/parts/interceptors_custom.txt +16 -16
- data/doc/manual/parts/interceptors_ordering.txt +5 -5
- data/doc/manual/parts/libraries_creating.txt +18 -18
- data/doc/manual/parts/libraries_using.txt +19 -19
- data/doc/manual/parts/logging_configuration.txt +13 -13
- data/doc/manual/parts/logging_logfactory.txt +21 -22
- data/doc/manual/parts/models_models.txt +8 -8
- data/doc/manual/parts/models_overview.txt +1 -1
- data/doc/manual/parts/models_pipelines.txt +22 -22
- data/doc/manual/{manual.css → stylesheets/manual.css} +83 -10
- data/doc/manual/stylesheets/ruby.css +17 -0
- data/lib/needle/definition-context.rb +3 -2
- data/lib/needle/lifecycle/proxy.rb +1 -1
- data/lib/needle/version.rb +1 -1
- metadata +94 -85
@@ -1,7 +1,7 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<title>Needle Manual :: Chapter 9: Customizing Needle</title>
|
4
|
-
<link type="text/css" rel="stylesheet" href="manual.css" />
|
4
|
+
<link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
|
5
5
|
</head>
|
6
6
|
|
7
7
|
<body>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.2.
|
18
|
-
Manual Last Updated: <strong>
|
17
|
+
Needle Version: <strong>1.2.1</strong><br />
|
18
|
+
Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -208,7 +208,15 @@
|
|
208
208
|
|
209
209
|
<div id="content">
|
210
210
|
|
211
|
-
|
211
|
+
<div class="top"><div class="prevnext">
|
212
|
+
|
213
|
+
<a href="chapter-8.html">Previous (8. Service Libraries)</a> |
|
214
|
+
|
215
|
+
<a href="index.html">Up</a>
|
216
|
+
|
217
|
+
</div></div>
|
218
|
+
|
219
|
+
<h1>9. Customizing Needle</h1>
|
212
220
|
|
213
221
|
|
214
222
|
|
@@ -222,27 +230,31 @@
|
|
222
230
|
<div class="section">
|
223
231
|
<p>By default, when you create a namespace in Needle, the namespace is registered as a service. The type of the service is determined by the <code>:namespace_impl_factory</code> service, which (by default) returns the <code>Needle::Container</code> class.</p>
|
224
232
|
|
233
|
+
|
225
234
|
<p>You can specify your own custom implementation for namespaces by registering your own <code>:namespace_impl_factory</code> service. In fact, each namespace can have its own implementation of subnamespaces—just register a <code>:namespace_impl_factory</code> in each one that you want to be specialized.</p>
|
226
235
|
|
236
|
+
|
227
237
|
<p>Here’s a contrived example. Suppose you want each namespace to keep track of the precise time that it was created.</p>
|
228
238
|
|
229
239
|
|
230
|
-
<
|
231
|
-
|
232
|
-
|
240
|
+
<div class='figure'>
|
241
|
+
<span class='caption'>Custom namespace implementations [ruby]</span>
|
242
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="keyword">class </span><span class="class">TimeTrackerNamespace</span> <span class="punct"><</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Container</span>
|
243
|
+
<span class="ident">attr_reader</span> <span class="symbol">:birth_date</span>
|
244
|
+
|
245
|
+
<span class="keyword">def </span><span class="method">initialize</span><span class="punct">(</span> <span class="punct">*</span><span class="ident">args</span> <span class="punct">)</span>
|
246
|
+
<span class="keyword">super</span>
|
247
|
+
<span class="attribute">@birth_date</span> <span class="punct">=</span> <span class="constant">Time</span><span class="punct">.</span><span class="ident">now</span>
|
248
|
+
<span class="keyword">end</span>
|
249
|
+
<span class="keyword">end</span>
|
233
250
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
251
|
+
<span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span>
|
252
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:namespace_impl_factory</span> <span class="punct">)</span> <span class="punct">{</span> <span class="constant">TimeTrackerNamespace</span> <span class="punct">}</span>
|
253
|
+
|
254
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">namespace</span> <span class="symbol">:hello</span>
|
255
|
+
<span class="ident">p</span> <span class="ident">reg</span><span class="punct">.</span><span class="ident">hello</span><span class="punct">.</span><span class="ident">birth_date</span></pre></div></td></tr></table></div></div>
|
239
256
|
|
240
|
-
reg = Needle::Registry.new
|
241
|
-
reg.register( :namespace_impl_factory ) { TimeTrackerNamespace }
|
242
257
|
|
243
|
-
reg.namespace :hello
|
244
|
-
p reg.hello.birth_date
|
245
|
-
</pre>
|
246
258
|
<p>In general, you’ll be better off having your custom implementation extend <code>Needle::Container</code>, although the only <em>real</em> requirement is that your implementation publish the same interface as the default namespace implementation.</p>
|
247
259
|
</div>
|
248
260
|
|
@@ -258,43 +270,46 @@
|
|
258
270
|
<div class="section">
|
259
271
|
<p>When you attach an interceptor to a service, that new interceptor is wrapped in a definition object that includes various metadata about the interceptor, including its implementation, its priority, its name, and so forth. The implementation of this interceptor definition is determined by the value of the <code>:interceptor_impl_factory</code> service, which by default returns <code>Needle::Interceptor</code>.</p>
|
260
272
|
|
273
|
+
|
261
274
|
<p>It is this wrapper object that allows interceptor definitions to be done using method chaining:</p>
|
262
275
|
|
263
276
|
|
264
|
-
<
|
265
|
-
|
266
|
-
</pre>
|
277
|
+
<div class='figure'>
|
278
|
+
<span class='caption'>Configuring an interceptor [ruby]</span>
|
279
|
+
<div class='body'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="ident">reg</span><span class="punct">.</span><span class="ident">intercept</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">).</span><span class="ident">with</span> <span class="punct">{</span> <span class="punct">...</span> <span class="punct">}.</span><span class="ident">with_options</span><span class="punct">(...)</span></pre></div></div></div>
|
280
|
+
|
281
|
+
|
267
282
|
<p>If you wish to add custom, domain-specific functionality to the interceptor wrapper, you can register your own implementation of the <code>:interceptor_impl_factory</code>. Consider the following contrived example, where an “only_if” clause is given to determine when the interceptor should be invoked.</p>
|
268
283
|
|
269
284
|
|
270
|
-
<
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
</pre>
|
285
|
+
<div class='figure'>
|
286
|
+
<span class='caption'>Advanced configuration of an interceptor [ruby]</span>
|
287
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="keyword">class </span><span class="class">OnlyIfInterceptor</span> <span class="punct"><</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Interceptor</span>
|
288
|
+
<span class="keyword">def </span><span class="method">only_if</span><span class="punct">(</span> <span class="punct">&</span><span class="ident">block</span> <span class="punct">)</span>
|
289
|
+
<span class="attribute">@only_if</span> <span class="punct">=</span> <span class="ident">block</span>
|
290
|
+
<span class="constant">self</span>
|
291
|
+
<span class="keyword">end</span>
|
292
|
+
|
293
|
+
<span class="keyword">def </span><span class="method">action</span>
|
294
|
+
<span class="ident">action_proc</span> <span class="punct">=</span> <span class="keyword">super</span>
|
295
|
+
<span class="ident">lambda</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">chain</span><span class="punct">,</span><span class="ident">ctx</span><span class="punct">|</span>
|
296
|
+
<span class="keyword">if</span> <span class="attribute">@only_if</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span> <span class="ident">chain</span><span class="punct">,</span> <span class="ident">ctx</span> <span class="punct">)</span>
|
297
|
+
<span class="ident">action_proc</span><span class="punct">.</span><span class="ident">call</span><span class="punct">(</span> <span class="ident">chain</span><span class="punct">,</span> <span class="ident">ctx</span> <span class="punct">)</span>
|
298
|
+
<span class="keyword">else</span>
|
299
|
+
<span class="ident">chain</span><span class="punct">.</span><span class="ident">process_next</span><span class="punct">(</span> <span class="ident">ctx</span> <span class="punct">)</span>
|
300
|
+
<span class="keyword">end</span>
|
301
|
+
<span class="keyword">end</span>
|
302
|
+
<span class="keyword">end</span>
|
303
|
+
<span class="keyword">end</span>
|
304
|
+
|
305
|
+
<span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span>
|
306
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:interceptor_impl_factory</span> <span class="punct">)</span> <span class="punct">{</span> <span class="constant">OnlyIfInterceptor</span> <span class="punct">}</span>
|
307
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">)</span> <span class="punct">{</span> <span class="constant">Bar</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
|
308
|
+
|
309
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">intercept</span><span class="punct">(</span> <span class="symbol">:foo</span> <span class="punct">).</span>
|
310
|
+
<span class="ident">with</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">c</span><span class="punct">|</span> <span class="ident">c</span><span class="punct">.</span><span class="ident">logging_interceptor</span> <span class="punct">}.</span>
|
311
|
+
<span class="ident">only_if</span> <span class="punct">{</span> <span class="punct">|</span><span class="ident">ch</span><span class="punct">,</span><span class="ident">ctx</span><span class="punct">|</span> <span class="ident">something_is_true</span><span class="punct">(</span> <span class="ident">ch</span><span class="punct">,</span> <span class="ident">ctx</span> <span class="punct">)</span> <span class="punct">}.</span>
|
312
|
+
<span class="ident">with_options</span><span class="punct">(...)</span></pre></div></td></tr></table></div></div>
|
298
313
|
</div>
|
299
314
|
|
300
315
|
|
@@ -309,33 +324,43 @@
|
|
309
324
|
<div class="section">
|
310
325
|
<p>A <em>definition context</em> is used when registering services using any of the <code>#define</code> interfaces. For example, <code>Container#define</code> yields an instance of a definition context to the given block, and <code>Container#define!</code> uses the block in an <code>instance_eval</code> on a definition context.</p>
|
311
326
|
|
327
|
+
|
312
328
|
<p>The default implementation used for definition contexts is defined by the <code>:definition_context_factory</code> service. By default, this service returns <code>Needle::DefinitionContext</code>, but you can specify your own definition context implementations by overriding this service. In fact, each namespace could have its own definition context implementation, if needed.</p>
|
313
329
|
|
330
|
+
|
314
331
|
<p>Consider the following contrived example, where you want to provide a convenient way to register services of type Hash.</p>
|
315
332
|
|
316
333
|
|
317
|
-
<
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
end
|
334
|
+
<div class='figure'>
|
335
|
+
<span class='caption'>Custom DefinitionContext example [ruby]</span>
|
336
|
+
<div class='body'><table border='0' cellpadding='0' cellspacing='0'><tr><td class='lineno'>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></td><td width='100%'><link rel='stylesheet' type='text/css' href='stylesheets/ruby.css' /><div class='ruby'><pre><span class="keyword">class </span><span class="class">MyDefinitionContext</span> <span class="punct"><</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">DefinitionContext</span>
|
337
|
+
<span class="keyword">def </span><span class="method">register_hash</span><span class="punct">(</span> <span class="ident">name</span><span class="punct">,</span> <span class="ident">opts</span><span class="punct">={}</span> <span class="punct">)</span>
|
338
|
+
<span class="ident">this_container</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="ident">name</span><span class="punct">,</span> <span class="ident">opts</span> <span class="punct">)</span> <span class="punct">{</span> <span class="constant">Hash</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">}</span>
|
339
|
+
<span class="keyword">end</span>
|
340
|
+
<span class="keyword">end</span>
|
323
341
|
|
324
|
-
|
325
|
-
|
342
|
+
<span class="ident">reg</span> <span class="punct">=</span> <span class="constant">Needle</span><span class="punct">::</span><span class="constant">Registry</span><span class="punct">.</span><span class="ident">new</span>
|
343
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">register</span><span class="punct">(</span> <span class="symbol">:definition_context_factory</span> <span class="punct">)</span> <span class="punct">{</span> <span class="constant">MyDefinitionContext</span> <span class="punct">}</span>
|
326
344
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
345
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">define</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">b</span><span class="punct">|</span>
|
346
|
+
<span class="ident">b</span><span class="punct">.</span><span class="ident">register_hash</span><span class="punct">(</span> <span class="symbol">:test1</span> <span class="punct">)</span>
|
347
|
+
<span class="ident">b</span><span class="punct">.</span><span class="ident">register_hash</span><span class="punct">(</span> <span class="symbol">:test2</span> <span class="punct">)</span>
|
348
|
+
<span class="keyword">end</span>
|
331
349
|
|
332
|
-
|
333
|
-
|
334
|
-
</pre>
|
350
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">test1</span><span class="punct">[</span><span class="symbol">:key</span><span class="punct">]</span> <span class="punct">=</span> <span class="punct">"</span><span class="string">value</span><span class="punct">"</span>
|
351
|
+
<span class="ident">reg</span><span class="punct">.</span><span class="ident">test2</span><span class="punct">[</span><span class="symbol">:foo</span><span class="punct">]</span> <span class="punct">=</span> <span class="punct">"</span><span class="string">bar</span><span class="punct">"</span></pre></div></td></tr></table></div></div>
|
335
352
|
</div>
|
336
353
|
|
337
354
|
|
338
355
|
|
356
|
+
<div class="bottom"><div class="prevnext">
|
357
|
+
|
358
|
+
<a href="chapter-8.html">Previous (8. Service Libraries)</a> |
|
359
|
+
|
360
|
+
<a href="index.html">Up</a>
|
361
|
+
|
362
|
+
</div></div>
|
363
|
+
|
339
364
|
|
340
365
|
</div>
|
341
366
|
|
data/doc/manual-html/index.html
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<title>Needle Manual</title>
|
4
|
-
<link type="text/css" rel="stylesheet" href="manual.css" />
|
4
|
+
<link type="text/css" rel="stylesheet" href="stylesheets/manual.css" />
|
5
5
|
</head>
|
6
6
|
|
7
7
|
<body>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Needle Version: <strong>1.2.
|
18
|
-
Manual Last Updated: <strong>
|
17
|
+
Needle Version: <strong>1.2.1</strong><br />
|
18
|
+
Manual Last Updated: <strong>2005-07-27 05:49 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -211,7 +211,7 @@
|
|
211
211
|
<p class="product-manual">Product Manual</p>
|
212
212
|
|
213
213
|
<p align="center">
|
214
|
-
<img src=""
|
214
|
+
<img src="needle.png"
|
215
215
|
alt="Needle: to the point -->" />
|
216
216
|
</p>
|
217
217
|
|
@@ -234,9 +234,9 @@
|
|
234
234
|
<table border='0' cellpadding='0' cellspacing='0' align='center'><tr><td>
|
235
235
|
<ul>
|
236
236
|
|
237
|
-
<li>
|
237
|
+
<li>Added Needle graphic (thanks to Bruce Williams)</li>
|
238
238
|
|
239
|
-
<li>Added
|
239
|
+
<li>Added syntax highlighting to code blocks</li>
|
240
240
|
|
241
241
|
</ul>
|
242
242
|
</table>
|
Binary file
|
@@ -87,8 +87,8 @@ a:hover {
|
|
87
87
|
}
|
88
88
|
|
89
89
|
#navigation ul, #navigation ol {
|
90
|
-
margin-left: 1.
|
91
|
-
padding-left: 1.
|
90
|
+
margin-left: 1.2em;
|
91
|
+
padding-left: 1.2em;
|
92
92
|
}
|
93
93
|
|
94
94
|
#navigation .license {
|
@@ -107,12 +107,6 @@ a:hover {
|
|
107
107
|
text-align: justify;
|
108
108
|
}
|
109
109
|
|
110
|
-
#content pre {
|
111
|
-
background: #FFE;
|
112
|
-
border: 1px dotted #AAA;
|
113
|
-
padding: 1em;
|
114
|
-
}
|
115
|
-
|
116
110
|
#content h1 {
|
117
111
|
background: #005;
|
118
112
|
color: #FFF;
|
@@ -186,7 +180,86 @@ a:hover {
|
|
186
180
|
text-align: center;
|
187
181
|
}
|
188
182
|
|
189
|
-
table.list
|
190
|
-
|
183
|
+
table.list {
|
184
|
+
margin: 2em;
|
185
|
+
border: 1px solid black;
|
186
|
+
background: #FFD;
|
187
|
+
padding: 0px;
|
188
|
+
border-spacing: 0px;
|
189
|
+
}
|
190
|
+
|
191
|
+
table.list th {
|
192
|
+
border-bottom: 1px solid #005;
|
191
193
|
padding-bottom: 5px;
|
194
|
+
background: #008;
|
195
|
+
color: white;
|
196
|
+
padding: 0.5em;
|
197
|
+
text-align: left;
|
198
|
+
}
|
199
|
+
|
200
|
+
table.list td {
|
201
|
+
padding: 0.2em;
|
202
|
+
text-align: left;
|
203
|
+
vertical-align: top;
|
204
|
+
border-bottom: 1px solid;
|
205
|
+
}
|
206
|
+
|
207
|
+
.prevnext {
|
208
|
+
padding: 0.5em 1em 0.5em 1em;
|
209
|
+
background: #557;
|
210
|
+
color: #FFF;
|
211
|
+
font-size: small;
|
212
|
+
font-weight: bold;
|
213
|
+
border: 1px solid #000;
|
214
|
+
}
|
215
|
+
|
216
|
+
.prevnext a {
|
217
|
+
color: #FF0;
|
218
|
+
}
|
219
|
+
|
220
|
+
.top .prevnext {
|
221
|
+
margin: 0 0 1em 0;
|
222
|
+
text-align: left;
|
223
|
+
}
|
224
|
+
|
225
|
+
.bottom .prevnext {
|
226
|
+
margin: 1em 0 0 0;
|
227
|
+
text-align: right;
|
228
|
+
}
|
229
|
+
|
230
|
+
.figure {
|
231
|
+
border: 1px solid black;
|
232
|
+
line-height: normal;
|
233
|
+
background: #FFD;
|
234
|
+
margin: 2em;
|
235
|
+
}
|
236
|
+
|
237
|
+
.figure .caption {
|
238
|
+
background: #008;
|
239
|
+
color: white;
|
240
|
+
font-weight: bold;
|
241
|
+
font-size: small;
|
242
|
+
padding: 4px 24px 4px 8px;
|
243
|
+
margin-left: -4px;
|
244
|
+
border: 1px dotted #77F;
|
245
|
+
}
|
246
|
+
|
247
|
+
.figure .body {
|
248
|
+
padding-left: 1em;
|
249
|
+
}
|
250
|
+
|
251
|
+
.figure pre {
|
252
|
+
padding: 0px;
|
253
|
+
background: transparent;
|
254
|
+
border: none;
|
255
|
+
font-size: small;
|
256
|
+
font-family: mono;
|
257
|
+
}
|
258
|
+
|
259
|
+
.figure .lineno {
|
260
|
+
text-align: right;
|
261
|
+
color: #B00;
|
262
|
+
font-family: mono;
|
263
|
+
font-size: small;
|
264
|
+
padding-right: 1em;
|
192
265
|
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
.ruby .normal {}
|
2
|
+
.ruby .comment { color: #005; font-style: italic; }
|
3
|
+
.ruby .keyword { color: #A00; font-weight: bold; }
|
4
|
+
.ruby .method { color: #077; }
|
5
|
+
.ruby .class { color: #074; }
|
6
|
+
.ruby .module { color: #050; }
|
7
|
+
.ruby .punct { color: #447; font-weight: bold; }
|
8
|
+
.ruby .symbol { color: #099; }
|
9
|
+
.ruby .string { color: #944; }
|
10
|
+
.ruby .char { color: #F07; }
|
11
|
+
.ruby .ident { color: #004; }
|
12
|
+
.ruby .constant { color: #07F; }
|
13
|
+
.ruby .regex { color: #B66; }
|
14
|
+
.ruby .number { color: #D55; }
|
15
|
+
.ruby .attribute { color: #377; }
|
16
|
+
.ruby .global { color: #3B7; }
|
17
|
+
.ruby .expr { color: #227; }
|
data/doc/manual/chapter.erb
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
<div class="top"><div class="prevnext">
|
2
|
+
<% if previous_chapter %>
|
3
|
+
<a href="chapter-<%= previous_chapter.index %>.html">Previous (<%= previous_chapter.index %>. <%= previous_chapter.title %>)</a> |
|
4
|
+
<% end %>
|
5
|
+
<a href="index.html">Up</a>
|
6
|
+
<% if next_chapter %>
|
7
|
+
| <a href="chapter-<%= next_chapter.index %>.html">Next (<%= next_chapter.index %>. <%= next_chapter.title %>)</a>
|
8
|
+
<% end %>
|
9
|
+
</div></div>
|
10
|
+
|
1
11
|
<h1><%= object.index %>. <%= object.title %></h1>
|
2
12
|
|
3
13
|
<% object.sections.each do |section|
|
@@ -16,3 +26,13 @@
|
|
16
26
|
</div>
|
17
27
|
|
18
28
|
<% end %>
|
29
|
+
|
30
|
+
<div class="bottom"><div class="prevnext">
|
31
|
+
<% if previous_chapter %>
|
32
|
+
<a href="chapter-<%= previous_chapter.index %>.html">Previous (<%= previous_chapter.index %>. <%= previous_chapter.title %>)</a> |
|
33
|
+
<% end %>
|
34
|
+
<a href="index.html">Up</a>
|
35
|
+
<% if next_chapter %>
|
36
|
+
| <a href="chapter-<%= next_chapter.index %>.html">Next (<%= next_chapter.index %>. <%= next_chapter.title %>)</a>
|
37
|
+
<% end %>
|
38
|
+
</div></div>
|
Binary file
|
Binary file
|
data/doc/manual/manual.rb
CHANGED
@@ -11,6 +11,7 @@ require 'erb'
|
|
11
11
|
require 'fileutils'
|
12
12
|
require 'yaml'
|
13
13
|
require 'redcloth'
|
14
|
+
require 'syntax/convertors/html'
|
14
15
|
|
15
16
|
module Needle
|
16
17
|
module Manual
|
@@ -100,10 +101,79 @@ module Needle
|
|
100
101
|
def initialize( index, title, content )
|
101
102
|
@index = index
|
102
103
|
@title = RedCloth.new( title ).to_html.gsub( %r{</?p>}, "" ) if title
|
103
|
-
@content =
|
104
|
+
@content = FigureContainer.new( content || "" )
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
108
|
+
class FigureContainer
|
109
|
+
def initialize( content )
|
110
|
+
@content = content
|
111
|
+
@html = nil
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_html
|
115
|
+
return @html if @html
|
116
|
+
extract_figures
|
117
|
+
convert_to_html
|
118
|
+
replace_figures
|
119
|
+
@html
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
Figure = Struct.new( :opts, :body )
|
125
|
+
|
126
|
+
def extract_figures
|
127
|
+
@figures = []
|
128
|
+
@content.gsub!( /^\{\{\{(.*?)?\n(.*?)\n\}\}\}$/m ) do
|
129
|
+
body = $2.strip
|
130
|
+
opts = Hash[*$1.strip.split(/,/).map{|p| p.split(/=/)}.flatten]
|
131
|
+
@figures << Figure.new( opts, body )
|
132
|
+
"====#{@figures.length-1}===="
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def convert_to_html
|
137
|
+
@html = ( @content.length < 1 ? "" :
|
138
|
+
RedCloth.new( @content ).to_html )
|
139
|
+
end
|
140
|
+
|
141
|
+
def replace_figures
|
142
|
+
@html.gsub!( /<p>====(.*?)====<\/p>/ ) do
|
143
|
+
figure = @figures[$1.to_i]
|
144
|
+
lang = figure.opts["lang"]
|
145
|
+
caption = figure.opts["caption"] || "Figure"
|
146
|
+
caption << " [#{lang}]" if lang
|
147
|
+
|
148
|
+
body = figure.body
|
149
|
+
|
150
|
+
if lang
|
151
|
+
convertor = Syntax::Convertors::HTML.for_syntax( lang )
|
152
|
+
|
153
|
+
body = "<link rel='stylesheet' type='text/css' " +
|
154
|
+
"href='stylesheets/#{lang}.css' />" +
|
155
|
+
"<div class='#{lang}'>" +
|
156
|
+
convertor.convert( body ) +
|
157
|
+
"</div>"
|
158
|
+
end
|
159
|
+
|
160
|
+
if figure.opts["number"] && eval(figure.opts["number"])
|
161
|
+
line = 1
|
162
|
+
numbers = ""
|
163
|
+
body.each_line { numbers << "#{line}<br />"; line += 1 }
|
164
|
+
body = "<table border='0' cellpadding='0' cellspacing='0'>" +
|
165
|
+
"<tr><td class='lineno'>#{numbers}</td>" +
|
166
|
+
"<td width='100%'>#{body}</td></tr></table>"
|
167
|
+
end
|
168
|
+
|
169
|
+
"<div class='figure'>\n" +
|
170
|
+
"<span class='caption'>#{caption}</span>\n" +
|
171
|
+
"<div class='body'>#{body}</div>" +
|
172
|
+
"</div>"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
107
177
|
YAML.add_private_type( 'file' ) { |type_id, value| File.read( value ) rescue "" }
|
108
178
|
YAML.add_private_type( 'eval' ) { |type_id, value| eval( value ) }
|
109
179
|
|
@@ -200,11 +270,15 @@ if __FILE__ == $0
|
|
200
270
|
template = File.open( "chapter.erb" ) { |file| ERB.new( file.read ) }
|
201
271
|
template.filename = "chapter.erb"
|
202
272
|
|
203
|
-
manual.chapters.
|
273
|
+
manual.chapters.each_with_index do |object, index|
|
204
274
|
log_action "Processing chapter ##{object.index}..."
|
275
|
+
|
276
|
+
previous_chapter = ( index < 1 ? nil : manual.chapters[index-1] )
|
277
|
+
next_chapter = manual.chapters[index+1]
|
278
|
+
|
205
279
|
File.open( File.join( output_path, "chapter-#{object.index}.html" ), "w" ) do |file|
|
206
|
-
guts = template.result
|
207
|
-
file << page.result
|
280
|
+
guts = template.result( binding )
|
281
|
+
file << page.result( binding )
|
208
282
|
end
|
209
283
|
end
|
210
284
|
|
@@ -231,10 +305,11 @@ if __FILE__ == $0
|
|
231
305
|
# end
|
232
306
|
|
233
307
|
log_action "Copying style sheets..."
|
234
|
-
FileUtils.
|
308
|
+
FileUtils.cp_r "stylesheets", output_path
|
235
309
|
|
236
310
|
log_action "Copying images..."
|
237
311
|
FileUtils.cp Dir["img/*.jpg"], output_path
|
312
|
+
FileUtils.cp Dir["img/*.png"], output_path
|
238
313
|
|
239
314
|
log_action "Done!"
|
240
315
|
end
|