summaryrefslogtreecommitdiffstats
path: root/source-builder/sb/asciidoc/examples/website/asciidocapi.txt
blob: bbf69e773f114e8fec10851b4a936f3378bd19a9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
AsciiDoc API
============

'asciidocapi' -- a Python API module for 'AsciiDoc'.


Introduction
------------
The 'asciidocapi' module implements a Python API for AsciiDoc. It
allows you to set `asciidoc(1)` program options, compile an AsciiDoc
source file and then interrogate the results.  The `asciidocapi.py`
module file contains the `AsciiDocAPI` wrapper class for
`asciidoc.py`.

.Benefits
- Stable API Shields the user from the undocumented and possibly
  volatile `asciidoc.py` internals.
- Easier to use and more flexible than the alternative of running
  `asciidoc(1)` as a separate process.
- Executes inside your application (better performance than running
  separate `asciidoc(1)` command processes).


Using asciidocapi
-----------------
To use the API just drop the `asciidocapi.py` file into your
application directory, import it and use the `AsciiDocAPI` class.  The
only requirement is that a compatible version of 'AsciiDoc' is already
installed -- simple, no setuptools to run, no Eggs to install, no
non-standard library dependencies.

You can find `asciidocapi.py` in the AsciiDoc
http://www.methods.co.nz/asciidoc/INSTALL.html#X1[distribution
archives] (version 8.4.1 or better).

Once you have `asciidocapi.py` Verify everything is working by running
the module doctests:

  python asciidocapi.py

If there are no messages then all is well.

The following minimal example compiles `mydoc.txt` to `mydoc.html`:

[source,python]
-------------------------------------------------------------------------------
from asciidocapi import AsciiDocAPI
asciidoc = AsciiDocAPI()
asciidoc.execute('mydoc.txt')
-------------------------------------------------------------------------------

The next interactive example uses file-like objects for input and output:

-------------------------------------------------------------------------------
$ python
Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from asciidocapi import AsciiDocAPI
>>> import StringIO
>>> infile = StringIO.StringIO('Hello *{author}*')
>>> outfile = StringIO.StringIO()
>>> asciidoc = AsciiDocAPI()
>>> asciidoc.options('--no-header-footer')
>>> asciidoc.attributes['author'] = 'Joe Bloggs'
>>> asciidoc.execute(infile, outfile, backend='html4')
>>> print outfile.getvalue()
<p>Hello <strong>Joe Bloggs</strong></p>

>>>
-------------------------------------------------------------------------------


Implementation Rationale
------------------------
.Leverage existing knowledge
The API maps directly onto the `asciidoc(1)` command -- this is
deliberate -- if you know the `asciidoc(1)` command learning the API
will be trivial. A nice side effect of this goal is that API and
command-line modes share the same code -- virtually no `asciidoc(1)`
code is specific to API usage.

.Simplicity
Implemented with a single Python module file (`asciidocapi.py`)
containing the 'AsciiDocAPI' API class. 'AsciiDocAPI'  contains just
one method plus a few attributes for processing options and result
messages.  No external setup tools and no non-standard library
dependencies are used or required.

.Loose coupling
The dependency between `asciidocapi.py` and `asciidoc.py` is minimal
-- the current `asciidocapi.py` module uses only two attributes and
one function from the `asciidoc.py` module.

.Why isn't the API baked right into the asciidoc.py command script?
1. You can't just drop `asciidoc.py` into your application because it
   requires all the related config files and filters -- complex and
   unnecessary since all this was already done when you installed
   AsciiDoc.
2. This scheme separates the API from the AsciiDoc application -- the
   API implementation can be extended or replaced independently of
   AsciiDoc.


API reference
-------------

[[X2]]
Class `AsciiDocAPI(object)`
~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the 'AsciiDoc' API class.

Instance attributes
^^^^^^^^^^^^^^^^^^^
`asciidoc`::
The imported `asciidoc.py` module.

`attributes`::
A dictionary of AsciiDoc attribute values passed to AsciiDoc.

- Setting an attribute value to `None` (`name: None`) will undefine
  (delete) the attribute (this in addition to the `name!` attribute
  name format that the `asciidoc(1)` command uses).
- To simply define an attribute set the attribute value to a blank
  string (`name: ''`) 

`cmd`::
The file path of the `asciidoc.py` script. Set by the `__init__`
method.

`messages`::
A chronologically ordered list of message strings generated during
AsciiDoc execution (last message at the end of the list).

`options`::
An instance of the <<X1,Options class>>. Contains a list of command
options passed to AsciiDoc.

Instance methods
^^^^^^^^^^^^^^^^
`__init__(self, asciidoc_py=None)`::
Locate and import `asciidoc.py` module and verify API compatibility.
Initialize instance attributes. A search for the `asciidoc` module is
made in the following order:

. Use the `ASCIIDOC_PY` environment variable if it is set.
. Use the `asciidoc_py` argument if it is set.
. Search the environment 'PATH' for `asciidoc.py`, `asciidoc.pyc` and
  `asciidoc` (in that order).
. Finally repeat the previous search in the current working directory.

`execute(self, infile, outfile=None, backend=None)`::
Compile `infile` to `outfile` using `backend` format.  `infile` and
`outfile` can be file path strings or file-like objects. `backend` is
name of 'AsciiDoc' backend (takes same values as `asciidoc(1)` command
`--backend` option). If `outfile` or `backend` are `None` then their
respective `asciidoc(1)` defaults are used.


[[X1]]
Class `Options(object)`
~~~~~~~~~~~~~~~~~~~~~~~
Stores `asciidoc(1)` command options. You can use any `asciidoc(1)`
options with the exception of the `--doctest` and `--filter` options.

Instance attributes
^^^^^^^^^^^^^^^^^^^
`values`::
The list of `(name,value)` command option tuples.

Instance methods
^^^^^^^^^^^^^^^^
`__call__(self, name, value=None)`::
A shortcut for the `append` method. Example:

  opts = Options()
  opts('--verbose')

`append(self, name, value=None)`::
Append `(name,value)` to the options list. Example:

  opts = Options()
  opts.append('--conf-file', 'blog.conf')


Class `AsciiDocError(Exception)`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Thrown by the <<X2,AsciiDocAPI class>> when an 'AsciiDoc' execution
error occurs.