Finish doctest documentation update
[pylit.git] / rstdocs / tutorial / index.txt
blobd95dff2e6b08b852bfec086b7f20c2294116e47c
1 .. -*- rst-mode -*-
2 .. 
3   restindex
4       crumb: Tutorial
5       page-title: PyLit - Tutorial
6   /restindex
8 How to write program documents with PyLit
9 =========================================
11 .. sectnum::
12 .. contents::
14 Hello world
15 -----------
17 We start with a classical example in Python_
19 .. include:: hello.py
20      :literal:
22 save it as ``hello.py`` and convert to a `reStructured Text`_ document
23 with ``pylit.py``::
25   #> python pylit.py hello.py
26   extract written to hello.py.txt
28 The output file ``hello.py.txt`` looks like
30 .. include:: hello.py.txt
31      :literal:
33 We can see the difference between "commented code" and "code living in a
34 text document".
36 Points to mention:
38 * One can start literate programming with an existing code file (and without
39   knowledge of reStructured Text syntax).
40   
41 * *Documentation* is uncommented (if it is separated from code by a
42   blank line and has a recognised comment string at the start of each line).
44 * A double colon is added at the end of the text block. It is the
45   `reStructured Text`_ marker for the following `literal block`_.
46   (No marker is added, if the text block already ends with a double colon.)
48 * *Code* is indented to form a literal block. It will be printed using a
49   monospaced font and without reStructured Text substitutions.
51 * PyLit adds ".txt" to the filename for the text version.
53 Now we can add some more documentation and a link (of course, knowledge of
54 `reStructured Text syntax`_ helps in this stage):
56 .. include:: hello_2.py.txt
57      :literal:
59 Pretty-printed with docutils, it looks like
61 .. admonition:: hello_2
63    .. include:: hello_2.py.txt
65 If we re-convert the result to code, ::
67   #> python pylit.py hello_2.py.txt
68   extract written to hello_2.py
70 we get
72 .. include:: hello_2.py
73      :literal:
75 Points to mention:
77 * The double colon that was added in the first conversion is not stripped in
78   the re-conversion. 
79   
80   (Generally, a round-trip should not introduce changes after the first
81   cycle. This way it is ensured that the line-numbers are the same in text
82   and code source.)
83   
84 * The code block ends at the first non indented line (Precisely, at the
85   first line that is not more indented than the preceding text block.)
88 Textblocks and Comments
89 -----------------------
91 Comment lines are only transformed to a text block, if they
93 * start with a matching `comment string` (whitespace counts!, the Python
94   default is ``'# '``), and
95 * are separated from non-text lines by at least one blank [#]_ line
97 Otherwise, they are kept as commented code.
99 An example will illustrate this. The code::
101   # 99bottles.py -- print the famous "99 bottles of beer" song lyrics
102   
103   # Introductory example to literate programming
104   #
105   # count down from 99 to 1
106   for bottles in range(99,0,-1):
107       ....
109 is mapped to text as::
111   99bottles.py -- print the famous "99 bottles of beer" song lyrics
112   
113   ::
115     # Introductory example to literate programming
116     #
117     # count down from 99 to 1
118     for bottles in range(99,0,-1):
119         ....
121 The comment in the 5th line marks the "secondary documentation" as part of
122 the code block.
124 However, ::
126   # 99bottles.py -- print the famous "99 bottles of beer" song lyrics
127   #
128   # Introductory example to literate programming
129   
130   # count down from 99 to 1
131   for bottles in range(99,0,-1):
132       ....
134 is mapped to text as::
136   99bottles.py -- print the famous "99 bottles of beer" song lyrics
138   Introductory example to literate programming
139   
140   ::
141   
142     # count down from 99 to 1
143     for bottles in range(99,0,-1):
144         ....
146 The comment in the 2nd line is removed, as it is inside a documentation block.
148 .. [#] a line is considered blank, if it contains only whitespace
151 Non-code literal block
152 ----------------------
154 How can I include a literal block that should not be in the executable code
155 (e.g. an example, an earlier version or variant)?
157 Workarounds:
158   
159 - Use a `parsed-literal block`_ directive and mark lines containing
160   "accidential" markup as `inline literals`_. E.g. ::
161   
162     This will be printed as literal block but not become part of the source
163     code:
164     
165     .. parsed-literal::
166     
167       print "code example that should not run"
168       ``result = 5 *not_bold* 2``
169     
170   will be typeset as
172   
173     This will be printed as literal block but not become part of the source
174     code:
175     
176     .. parsed-literal::
177     
178       print "code example that should not run"
179       ``result = 5 *not_bold* 2``
182 - Python session examples and doctests can use `doctest block`_ syntax:
184   No double colon! Start first line of block with ``>>>``.
186 - Use a "code-block" directive and set the `code_block_marker` option
187   or use a distinct directive for ordinary literal blocks.
188   
189   Drawback: such directives are not part of the core rst syntax (yet) but
190   must be defined in an add-on (see `syntax highlight`_ for examples).
191     
195 File Headers
196 ------------
198 Sometimes code needs to remain on the first line(s) of the document to be
199 valid. The most common example is the shebang_ line that tells a POSIX shell
200 how to process an executable file. In Python, the magic comment specifying
201 the `source code encoding`_ must occure on line one or two:
203 .. include:: hello_with_header.py
204      :literal:
206 Headers are converted to a comment in the text source: 
208 .. include:: hello_with_header.py.txt
209      :literal:
211 Pretty-printed with docutils, it looks like
213 .. admonition:: hello_with_header
215    .. include:: hello_with_header.py.txt
217 Everything before the first text block (i.e. before the first paragraph
218 using the matching comment string) will be hidden in HTML or PDF output.
220 It may come as surprise that a part of the file is not "printed".
221 (In the case that there is no matching comment at all, the complete code
222 source will become a comment, however, in this case it is not likely
223 the source is a literate program anyway). But there are advantages also:
225 * line numbers are kept during the text <--> code conversion (which would be
226   impossible with a literal block marker as this needs to be at the end of
227   the preceding paragraph)
228 * you can hide a repeating (or boring) header in a project consisting of
229   many source files.
231 If needed for the documentation, it is possible to repeat the header in the
232 the first text block, e.g. using a `parsed literal block`_:
234 .. parsed-literal::
236   #!/usr/bin/env python
237   # -*- coding: iso-8859-1 -*-
240 Doctests
241 --------
243 Pylit supports `Python doctests`_ in a literate script. 
245 We add a `doctest block`_ [#]_ to our example:
247 .. include:: hello_with_doctest.py
248    :literal:
250 Now try it with ::
252   #>  python -c "import doctest; doctest.testfile('hello_with_doctest.py')"
253   
254 There is no output. So everything is OK? Unfortunatly not:
255 ``doctest.testfile`` does not find the test, as it is "hidden" in a comment.
256 [#]_ 
258 Pylit converts the source to the text version (stripping the comments),
259 feeds it to the doctest_ module's `Advanced API`_ (introduced in Python
260 2.4), and we get ::
262   #> pylit --doctest hello_with_doctest.py  
263   **********************************************************************
264   File "hello_with_doctest.py", line 3, in 
265   Failed example:
266       execfile("hello_with_doctest.py")
267   Expected:
268       Hello world
269   Got:
270       Hello world.
272 Ah yes, we forgot the full-stop in our test. Adding it and testing again::
274   #> pylit --doctest hello_with_doctest_2.py  
275   0 failures in 1 tests
277 The printed summary will ensure us that the test actually passed.
279 Read more about doctests in the `literate doctests example`_.
282 .. [#] There is no double colon before the doctest; a doctest block is
283        recognised by starting with the Python interpreter prompt ``>>>``
284        instead.
286 .. [#] The tests will be found, if ``doctest.testfile`` is run on the text
287        source, i.e.  
288        ``python -c "import doctest; doctest.testfile('hello_with_doctest.py.txt')"``
291 Including files
292 ---------------
294 PyLit does not allow the specification of a separate output file for
295 individual code blocks like e.g. noweb_. The "dual source" concept limits
296 the choice to one output file per input file. However, this can be
297 compensated by the use of the `include directive`_.
299 Let us assume that for some reason, the friendly greeting should be defined
300 in a separate file ``greeting.py``:
302 .. include:: greeting.py
303      :literal:
305 The documentation of the calling file can include the executed file
307 .. include:: hello_multifile.py
308      :literal:
310 Saved to ``hello_multifile.py.txt`` and pretty-printed with docutils, this
311 looks like
313 .. admonition:: hello_multifile
315    .. include:: hello_multifile.py.txt
318 * you have to convert both, ``greeting.py`` and ``hello_multifile.py``.
319   (Currently, pylit cannot do 'batch processing' of multiple input files.)
320   
322 .. References:
324 .. _reStructured Text: 
325      http://docutils.sourceforge.net/docs/user/rst/quickref.html
327 .. _Installation: ../download/index.html#installation
329 .. _shebang: http://en.wikipedia.org/wiki/Shebang_(Unix)
331 .. _reStructured Text syntax: 
332      http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html
334 .. _literal block: 
335      http://docutils.sourceforge.net/docs/user/rst/quickref.html#literal-blocks
337 .. _parsed literal block:
338      http://docutils.sourceforge.net/docs/ref/rst/directives.html#parsed-literal-block
339 .. _noweb: http://www.eecs.harvard.edu/~nr/noweb/
341 .. _include directive:
342      http://docutils.sourceforge.net/docs/ref/rst/directives.html#including-an-external-document-fragment
344 .. _source code encoding:
345     http://docs.python.org/tut/node4.html#SECTION004230000000000000000
347 .. _doctest:
348 .. _Python doctests: http://docs.python.org/lib/module-doctest.html
349 .. _Advanced API: http://docs.python.org/lib/doctest-advanced-api.html
350 .. _literate doctests example: ../examples/literate-doctests/index.html
352 .. _parsed-literal block: 
353     http://docutils.sf.net/docs/ref/rst/directives.html#parsed-literal-block
354 .. _doctest block: 
355     http://docutils.sf.net/docs/ref/rst/restructuredtext.html#doctest-blocks
356 .. _line block:
357 .. _line blocks:
358     http://docutils.sf.net/docs/ref/rst/restructuredtext.html#line-blocks
359 .. _inline literal:
360 .. _inline literals:
361     http://docutils.sf.net/docs/ref/rst/restructuredtext.html#inline-literals
362 .. _syntax highlight: ../features/syntax-highlight.html