~hudson-openstack/nova/trunk

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/lore/howto/extend-lore.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: Extending the Lore Documentation System</title>
 
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">Extending the Lore Documentation System</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Overview</a></li><li><a href="#auto1">Inputs and Outputs</a></li><ul><li><a href="#auto2">Creating New Inputs</a></li></ul></ol></div>
 
10
    <div class="content">
 
11
<span/>
 
12
 
 
13
<h2>Overview<a name="auto0"/></h2>
 
14
 
 
15
<p>The <a href="lore.html" shape="rect">Lore Documentation System</a>, out of the box, is
 
16
specialized for documenting Twisted.  Its markup includes CSS classes for
 
17
Python, HTML, filenames, and other Twisted-focused categories.  But don't
 
18
think this means Lore can't be used for other documentation tasks!  Lore is
 
19
designed to allow extensions, giving any Python programmer the ability to
 
20
customize Lore for documenting almost anything.</p>
 
21
 
 
22
<p>There are several reasons why you would want to extend Lore.  You may want
 
23
to attach file formats Lore does not understand to your documentation.  You
 
24
may want to create callouts that have special meanings to the reader, to give a
 
25
memorable appearance to text such as, <q>WARNING: This software was written by
 
26
  a frothing madman!</q>  You may want to create color-coding for a different
 
27
programming language, or you may find that Lore does not provide you with
 
28
enough structure to mark your document up completely.  All of these situations
 
29
can be solved by creating an extension.</p>
 
30
 
 
31
<h2>Inputs and Outputs<a name="auto1"/></h2>
 
32
 
 
33
<p>Lore works by reading the HTML source of your document, and producing
 
34
whatever output the user specifies on the command line.  If the HTML document
 
35
is well-formed XML that meets a certain minimum standard, Lore will be able to
 
36
to produce some output.  All Lore extensions will be written to redefine the
 
37
<em>input</em>, and most will redefine the output in some way.  The name of
 
38
the default input is <q>lore</q>.  When you write your extension, you will
 
39
come up with a new name for your input, telling Lore what rules to use to
 
40
process the file.</p>
 
41
 
 
42
<p>Lore can produce XHTML, LaTeX, and DocBook document formats, which can be
 
43
displayed directly if you have a user agent capable of viewing them, or
 
44
processed into a third form such as PostScript or PDF.  Another output is
 
45
called <q>lint</q>, after the static-checking utility for C, and is used for
 
46
the same reason: to statically check input files for problems.  The
 
47
<q>lint</q> output is just a stream of error messages, not a formatted
 
48
document, but is important because it gives users the ability to validate
 
49
their input before trying to process it.  For the first example, the only
 
50
output we will be concerned with is LaTeX.</p>
 
51
 
 
52
<h3>Creating New Inputs<a name="auto2"/></h3>
 
53
<p>Create a new input to tell Lore that your document is marked up differently
 
54
from a vanilla Lore document.  This gives you the power to define a new tag 
 
55
class, for example:</p>
 
56
<pre xml:space="preserve">
 
57
&lt;p&gt;The Frabjulon &lt;span class=&quot;productname&quot;&gt;Limpet 2000&lt;/span&gt;
 
58
is the &lt;span class=&quot;marketinglie&quot;&gt;industry-leading&lt;/span&gt; aquatic 
 
59
mollusc counter, bar none.&lt;/p&gt;
 
60
</pre>
 
61
 
 
62
<p>The above HTML is an instance of a new input to Lore, which we will call
 
63
MyHTML, to differentiate it from the <q>lore</q> input.  We want it to have
 
64
the following markup:</p> 
 
65
<ul>
 
66
  <li>A <code>productname</code> class for the &lt;span&gt; tag, which
 
67
  produces underlined text</li>
 
68
  <li>A <code>marketinglie</code> class for &lt;span&gt; tag, which
 
69
  produces larger type, bold text</li>
 
70
</ul>
 
71
<p>Note that I chose class names that are valid Python identifiers.  You will
 
72
see why shortly.  To get these two effects in Lore's HTML output, all we have
 
73
to do is create a cascading stylesheet (CSS), and use it in the Lore XHTML
 
74
Template.  However, we also want these effects to work in LaTeX, and we want
 
75
the output of lint to produce no warnings when it sees lines with these 2
 
76
classes.  To make LaTeX and lint work, we start by creating a plugin.</p>
 
77
 
 
78
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
79
 2
 
80
 3
 
81
 4
 
82
 5
 
83
 6
 
84
 7
 
85
 8
 
86
 9
 
87
10
 
88
11
 
89
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">implements</span>
 
90
 
 
91
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">plugin</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IPlugin</span>
 
92
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span>.<span class="py-src-variable">scripts</span>.<span class="py-src-variable">lore</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IProcessor</span>
 
93
 
 
94
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyHTML</span>(<span class="py-src-parameter">object</span>):
 
95
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IPlugin</span>, <span class="py-src-variable">IProcessor</span>)
 
96
 
 
97
    <span class="py-src-variable">name</span> = <span class="py-src-string">&quot;myhtml&quot;</span>
 
98
    <span class="py-src-variable">moduleName</span> = <span class="py-src-string">&quot;myhtml.factory&quot;</span>
 
99
</pre><div class="caption">
 
100
  Listing 1: The Plugin File - <a href="listings/lore/a_lore_plugin.py"><span class="filename">listings/lore/a_lore_plugin.py</span></a></div></div>
 
101
 
 
102
  <p>Create this file in a <code class="shell">twisted/plugins/</code>
 
103
  directory (<em>not</em> a package) which is located in a directory in the
 
104
  Python module search path.  See the <a href="../../core/howto/plugin.html" shape="rect">Twisted
 
105
  plugin howto</a> for more details on plugins.</p>
 
106
 
 
107
  <p>Users of your extension will pass the value of your plugin's <code class="python">name</code> attribute to lore with the <code class="shell">--input</code> parameter on the command line to select it.  For
 
108
  example, to select the plugin defined above, a user would pass <code class="shell">--input myhtml</code>.  The <code class="python">moduleName</code> attribute tells Lore where to find the code
 
109
  implementing the plugin.  In particular, this module should have a <code class="python">factory</code> attribute which defines a <code class="python">generator_</code>-prefixed method for each output format it
 
110
  supports.  Next we'll look at this module.</p>
 
111
 
 
112
<div class="py-listing"><pre><p class="py-linenumber">1
 
113
2
 
114
3
 
115
4
 
116
5
 
117
6
 
118
7
 
119
8
 
120
9
 
121
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">default</span>
 
122
<span class="py-src-keyword">from</span> <span class="py-src-variable">myhtml</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">spitters</span>
 
123
 
 
124
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyProcessingFunctionFactory</span>(<span class="py-src-parameter">default</span>.<span class="py-src-parameter">ProcessingFunctionFactory</span>):
 
125
    <span class="py-src-variable">latexSpitters</span>={<span class="py-src-variable">None</span>: <span class="py-src-variable">spitters</span>.<span class="py-src-variable">MyLatexSpitter</span>,
 
126
                   }
 
127
 
 
128
<span class="py-src-comment"># initialize the global variable factory with an instance of your new factory</span>
 
129
<span class="py-src-variable">factory</span>=<span class="py-src-variable">MyProcessingFunctionFactory</span>()
 
130
</pre><div class="caption">Listing 2: The Input
 
131
  Factory - <a href="listings/lore/factory.py-1"><span class="filename">listings/lore/factory.py-1</span></a></div></div>
 
132
 
 
133
<p>In Listing 2, we create a subclass of ProcessingFunctionFactory.  This
 
134
class provides a hook for you, a class variable named
 
135
<code>latexSpitters</code>.  This variable tells Lore
 
136
what new class will be generating LaTeX from your input format.  We redefine
 
137
<code>latexSpitters</code> to <code>MyLatexSpitter</code> in the subclass
 
138
because this
 
139
class knows what to do with the new input we have already defined.  Last, you
 
140
must define the module-level variable <code class="py-src-identifier">factory</code>.  It should be an instance with
 
141
  the same
 
142
interface as <code class="py-src-identifier">ProcessingFunctionFactory</code>
 
143
(e.g. an instance of a subclass, in this case, <code class="py-src-identifier">MyProcessingFunctionFactory</code>).</p>
 
144
 
 
145
<p>Now let's actually write some code to generate the LaTeX.  Doing this
 
146
requires at least a familiarity with the LaTeX language.  Search Google for
 
147
<q>latex tutorial</q> and you will find any number of useful LaTeX
 
148
resources.</p>
 
149
 
 
150
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
151
 2
 
152
 3
 
153
 4
 
154
 5
 
155
 6
 
156
 7
 
157
 8
 
158
 9
 
159
10
 
160
11
 
161
12
 
162
13
 
163
14
 
164
15
 
165
16
 
166
17
 
167
18
 
168
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">latex</span>
 
169
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span>.<span class="py-src-variable">latex</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">processFile</span>
 
170
<span class="py-src-keyword">import</span> <span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>
 
171
 
 
172
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyLatexSpitter</span>(<span class="py-src-parameter">latex</span>.<span class="py-src-parameter">LatexSpitter</span>):
 
173
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">visitNode_span_productname</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">node</span>):
 
174
        <span class="py-src-comment"># start an underline section in LaTeX</span>
 
175
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'\\underline{'</span>)
 
176
        <span class="py-src-comment"># process the node and its children</span>
 
177
        <span class="py-src-variable">self</span>.<span class="py-src-variable">visitNodeDefault</span>(<span class="py-src-variable">node</span>)
 
178
        <span class="py-src-comment"># end the underline block</span>
 
179
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'}'</span>)
 
180
 
 
181
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">visitNode_span_marketinglie</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">node</span>):
 
182
        <span class="py-src-comment"># this example turns on more than one LaTeX effect at once</span>
 
183
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'\\begin{bf}\\begin{Large}'</span>)
 
184
        <span class="py-src-variable">self</span>.<span class="py-src-variable">visitNodeDefault</span>(<span class="py-src-variable">node</span>)
 
185
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'\\end{Large}\\end{bf}'</span>)
 
186
</pre><div class="caption">Listing 3:
 
187
  spitters.py - <a href="listings/lore/spitters.py-1"><span class="filename">listings/lore/spitters.py-1</span></a></div></div>
 
188
 
 
189
<p>The method <code>visitNode_span_productname</code> is
 
190
our handler for &lt;span&gt; tags with the <code>class=&quot;productname&quot;</code>
 
191
identifier.  Lore knows to try methods <code>visitNode_span_*</code> and
 
192
<code>visitNode_div_*</code> whenever it encounters a new
 
193
class in one of these tags.  This is why the class names have to be valid
 
194
Python identifiers.</p>
 
195
 
 
196
<p>Now let's see what Lore does with these new classes with the following
 
197
input file:</p>
 
198
 
 
199
<div class="html-listing"><pre class="htmlsource">
 
200
&lt;html&gt;
 
201
  &lt;head&gt;
 
202
    &lt;title&gt;My First Example&lt;/title&gt;
 
203
  &lt;/head&gt;
 
204
  &lt;body&gt;
 
205
    &lt;h1&gt;My First Example&lt;/h1&gt;
 
206
    &lt;p&gt;The Frabjulon &lt;span class=&quot;productname&quot;&gt;Limpet 2000&lt;/span&gt;
 
207
    is the &lt;span class=&quot;marketinglie&quot;&gt;industry-leading&lt;/span&gt; aquatic 
 
208
    mollusc counter, bar none.&lt;/p&gt;
 
209
  &lt;/body&gt;
 
210
&lt;/html&gt;
 
211
 
 
212
</pre><div class="caption">Listing 4:
 
213
  1st_example.html - <a href="listings/lore/1st_example.html"><span class="filename">listings/lore/1st_example.html</span></a></div></div>
 
214
 
 
215
<p>First, verify that your package is laid out correctly.  Your directory
 
216
structure should look like this:</p>
 
217
 
 
218
<pre xml:space="preserve">
 
219
1st_example.html
 
220
myhtml/
 
221
       __init__.py
 
222
       factory.py
 
223
       spitters.py
 
224
twisted/plugins/
 
225
       a_lore_plugin.py
 
226
</pre>
 
227
 
 
228
<p>In the parent directory of myhtml (that is, <code>myhtml/..</code>), run
 
229
lore and pdflatex on the input:</p>
 
230
 
 
231
<pre class="shell" xml:space="preserve">
 
232
$ lore --input myhtml --output latex 1st_example.html 
 
233
[########################################] (*Done*)
 
234
 
 
235
$ pdflatex 1st_example.tex
 
236
[ . . . latex output omitted for brevity . . . ]
 
237
Output written on 1st_example.pdf (1 page, 22260 bytes).
 
238
Transcript written on 1st_example.log.
 
239
</pre>
 
240
 
 
241
<p>And here's what the rendered PDF looks like:</p>
 
242
 
 
243
<p><img src="../img/myhtml-output.png"/></p>
 
244
 
 
245
<p>What happens when we run lore on this file using the lint output?</p>
 
246
 
 
247
<pre class="shell" xml:space="preserve">
 
248
$ lore --input myhtml --output lint 1st_example.html
 
249
1st_example.html:7:47: unknown class productname
 
250
1st_example.html:8:38: unknown class marketinglie
 
251
[########################################] (*Done*)
 
252
</pre>
 
253
 
 
254
<p>Lint reports these classes as errors, even though our spitter knows how to
 
255
process them.  To fix this problem, we must add to <code class="py-filename">factory.py</code>.</p>
 
256
 
 
257
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
258
 2
 
259
 3
 
260
 4
 
261
 5
 
262
 6
 
263
 7
 
264
 8
 
265
 9
 
266
10
 
267
11
 
268
12
 
269
13
 
270
14
 
271
15
 
272
16
 
273
17
 
274
18
 
275
19
 
276
20
 
277
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">default</span>
 
278
<span class="py-src-keyword">from</span> <span class="py-src-variable">myhtml</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">spitters</span>
 
279
 
 
280
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyProcessingFunctionFactory</span>(<span class="py-src-parameter">default</span>.<span class="py-src-parameter">ProcessingFunctionFactory</span>):
 
281
    <span class="py-src-variable">latexSpitters</span>={<span class="py-src-variable">None</span>: <span class="py-src-variable">spitters</span>.<span class="py-src-variable">MyLatexSpitter</span>,
 
282
                   }
 
283
 
 
284
    <span class="py-src-comment"># redefine getLintChecker to validate our classes</span>
 
285
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getLintChecker</span>(<span class="py-src-parameter">self</span>):
 
286
        <span class="py-src-comment"># use the default checker from parent</span>
 
287
        <span class="py-src-variable">checker</span> = <span class="py-src-variable">lint</span>.<span class="py-src-variable">getDefaultChecker</span>()
 
288
        <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span> = <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span>.<span class="py-src-variable">copy</span>()
 
289
        <span class="py-src-variable">oldSpan</span> = <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span>[<span class="py-src-string">'span'</span>]
 
290
        <span class="py-src-variable">checkfunc</span>=<span class="py-src-keyword">lambda</span> <span class="py-src-variable">cl</span>: <span class="py-src-variable">oldSpan</span>(<span class="py-src-variable">cl</span>) <span class="py-src-keyword">or</span> <span class="py-src-variable">cl</span> <span class="py-src-keyword">in</span> [<span class="py-src-string">'marketinglie'</span>,
 
291
                                                   <span class="py-src-string">'productname'</span>]
 
292
        <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span>[<span class="py-src-string">'span'</span>] = <span class="py-src-variable">checkfunc</span>
 
293
        <span class="py-src-keyword">return</span> <span class="py-src-variable">checker</span>
 
294
 
 
295
<span class="py-src-comment"># initialize the global variable factory with an instance of your new factory</span>
 
296
<span class="py-src-variable">factory</span>=<span class="py-src-variable">MyProcessingFunctionFactory</span>()
 
297
</pre><div class="caption">Listing 5: Input
 
298
    Factory with Lint Support - <a href="listings/lore/factory.py-2"><span class="filename">listings/lore/factory.py-2</span></a></div></div>
 
299
 
 
300
<p>The method <code class="py-src-identifier">getLintChecker</code> is called
 
301
by Lore to produce the lint output.  This modification adds our classes to the
 
302
list of classes lint ignores:</p>
 
303
 
 
304
<pre class="shell" xml:space="preserve">
 
305
$ lore --input myhtml --output lint 1st_example.html
 
306
[########################################] (*Done*)
 
307
$ # Hooray!
 
308
</pre>
 
309
 
 
310
<p>Finally, there are two other sub-outputs of LaTeX, for a total of three
 
311
different ways that Lore can produce LaTeX: the default way, which produces as
 
312
output an entire, self-contained LaTeX document; with <code class="shell">--config section</code> on the command line, which produces a
 
313
LaTeX \section; and with <code class="shell">--config chapter</code>, which
 
314
produces a LaTeX \chapter.  To support these options as well, the solution is
 
315
to make the new spitter class a mixin, and use it with the <code class="py-src-identifier">SectionLatexSpitter</code> and <code class="py-src-identifier">ChapterLatexSpitter</code>, respectively.
 
316
Comments in the following listings tell you everything you need to know about
 
317
making these simple changes:</p>
 
318
 
 
319
<ul>
 
320
  <li><div class="py-listing"><pre><p class="py-linenumber"> 1
 
321
 2
 
322
 3
 
323
 4
 
324
 5
 
325
 6
 
326
 7
 
327
 8
 
328
 9
 
329
10
 
330
11
 
331
12
 
332
13
 
333
14
 
334
15
 
335
16
 
336
17
 
337
18
 
338
19
 
339
20
 
340
21
 
341
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">default</span>
 
342
<span class="py-src-keyword">from</span> <span class="py-src-variable">myhtml</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">spitters</span>
 
343
 
 
344
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyProcessingFunctionFactory</span>(<span class="py-src-parameter">default</span>.<span class="py-src-parameter">ProcessingFunctionFactory</span>):
 
345
    <span class="py-src-comment"># 1. add the keys &quot;chapter&quot; and &quot;section&quot; to latexSpitters to handle the</span>
 
346
    <span class="py-src-comment"># --config chapter and --config section options</span>
 
347
    <span class="py-src-variable">latexSpitters</span>={<span class="py-src-variable">None</span>: <span class="py-src-variable">spitters</span>.<span class="py-src-variable">MyLatexSpitter</span>,
 
348
                   <span class="py-src-string">&quot;section&quot;</span>: <span class="py-src-variable">spitters</span>.<span class="py-src-variable">MySectionLatexSpitter</span>,
 
349
                   <span class="py-src-string">&quot;chapter&quot;</span>: <span class="py-src-variable">spitters</span>.<span class="py-src-variable">MyChapterLatexSpitter</span>,
 
350
                   }
 
351
 
 
352
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getLintChecker</span>(<span class="py-src-parameter">self</span>):
 
353
        <span class="py-src-variable">checker</span> = <span class="py-src-variable">lint</span>.<span class="py-src-variable">getDefaultChecker</span>()
 
354
        <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span> = <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span>.<span class="py-src-variable">copy</span>()
 
355
        <span class="py-src-variable">oldSpan</span> = <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span>[<span class="py-src-string">'span'</span>]
 
356
        <span class="py-src-variable">checkfunc</span>=<span class="py-src-keyword">lambda</span> <span class="py-src-variable">cl</span>: <span class="py-src-variable">oldSpan</span>(<span class="py-src-variable">cl</span>) <span class="py-src-keyword">or</span> <span class="py-src-variable">cl</span> <span class="py-src-keyword">in</span> [<span class="py-src-string">'marketinglie'</span>,
 
357
                                                   <span class="py-src-string">'productname'</span>]
 
358
        <span class="py-src-variable">checker</span>.<span class="py-src-variable">allowedClasses</span>[<span class="py-src-string">'span'</span>] = <span class="py-src-variable">checkfunc</span>
 
359
        <span class="py-src-keyword">return</span> <span class="py-src-variable">checker</span>
 
360
 
 
361
<span class="py-src-variable">factory</span>=<span class="py-src-variable">MyProcessingFunctionFactory</span>()
 
362
</pre><div class="caption">factory.py - <a href="listings/lore/factory.py-3"><span class="filename">listings/lore/factory.py-3</span></a></div></div></li>
 
363
  <li><div class="py-listing"><pre><p class="py-linenumber"> 1
 
364
 2
 
365
 3
 
366
 4
 
367
 5
 
368
 6
 
369
 7
 
370
 8
 
371
 9
 
372
10
 
373
11
 
374
12
 
375
13
 
376
14
 
377
15
 
378
16
 
379
17
 
380
18
 
381
19
 
382
20
 
383
21
 
384
22
 
385
23
 
386
24
 
387
25
 
388
26
 
389
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">latex</span>
 
390
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">lore</span>.<span class="py-src-variable">latex</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">processFile</span>
 
391
<span class="py-src-keyword">import</span> <span class="py-src-variable">os</span>.<span class="py-src-variable">path</span>
 
392
 
 
393
<span class="py-src-comment"># 2. Create a new mixin that does what the old MyLatexSpitter used to do:</span>
 
394
<span class="py-src-comment"># process the new classes we defined</span>
 
395
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MySpitterMixin</span>:
 
396
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">visitNode_span_productname</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">node</span>):
 
397
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'\\underline{'</span>)
 
398
        <span class="py-src-variable">self</span>.<span class="py-src-variable">visitNodeDefault</span>(<span class="py-src-variable">node</span>)
 
399
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'}'</span>)
 
400
 
 
401
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">visitNode_span_marketinglie</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">node</span>):
 
402
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'\\begin{bf}\\begin{Large}'</span>)
 
403
        <span class="py-src-variable">self</span>.<span class="py-src-variable">visitNodeDefault</span>(<span class="py-src-variable">node</span>)
 
404
        <span class="py-src-variable">self</span>.<span class="py-src-variable">writer</span>(<span class="py-src-string">'\\end{Large}\\end{bf}'</span>)
 
405
 
 
406
<span class="py-src-comment"># 3. inherit from the mixin class for each of the three sub-spitters</span>
 
407
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyLatexSpitter</span>(<span class="py-src-parameter">MySpitterMixin</span>, <span class="py-src-parameter">latex</span>.<span class="py-src-parameter">LatexSpitter</span>):
 
408
    <span class="py-src-keyword">pass</span>
 
409
 
 
410
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MySectionLatexSpitter</span>(<span class="py-src-parameter">MySpitterMixin</span>, <span class="py-src-parameter">latex</span>.<span class="py-src-parameter">SectionLatexSpitter</span>):
 
411
    <span class="py-src-keyword">pass</span>
 
412
 
 
413
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyChapterLatexSpitter</span>(<span class="py-src-parameter">MySpitterMixin</span>, <span class="py-src-parameter">latex</span>.<span class="py-src-parameter">ChapterLatexSpitter</span>):
 
414
    <span class="py-src-keyword">pass</span>
 
415
</pre><div class="caption">spitters.py - <a href="listings/lore/spitters.py-2"><span class="filename">listings/lore/spitters.py-2</span></a></div></div></li>
 
416
</ul>
 
417
 
 
418
 
 
419
 
 
420
</div>
 
421
 
 
422
    <p><a href="index.html">Index</a></p>
 
423
    <span class="version">Version: 10.0.0</span>
 
424
  </body>
 
425
</html>
 
 
b'\\ No newline at end of file'