1 | AsciiDoc API |
---|
2 | ============ |
---|
3 | |
---|
4 | 'asciidocapi' -- a Python API module for 'AsciiDoc'. |
---|
5 | |
---|
6 | |
---|
7 | Introduction |
---|
8 | ------------ |
---|
9 | The 'asciidocapi' module implements a Python API for AsciiDoc. It |
---|
10 | allows you to set `asciidoc(1)` program options, compile an AsciiDoc |
---|
11 | source file and then interrogate the results. The `asciidocapi.py` |
---|
12 | module file contains the `AsciiDocAPI` wrapper class for |
---|
13 | `asciidoc.py`. |
---|
14 | |
---|
15 | .Benefits |
---|
16 | - Stable API Shields the user from the undocumented and possibly |
---|
17 | volatile `asciidoc.py` internals. |
---|
18 | - Easier to use and more flexible than the alternative of running |
---|
19 | `asciidoc(1)` as a separate process. |
---|
20 | - Executes inside your application (better performance than running |
---|
21 | separate `asciidoc(1)` command processes). |
---|
22 | |
---|
23 | |
---|
24 | Using asciidocapi |
---|
25 | ----------------- |
---|
26 | To use the API just drop the `asciidocapi.py` file into your |
---|
27 | application directory, import it and use the `AsciiDocAPI` class. The |
---|
28 | only requirement is that a compatible version of 'AsciiDoc' is already |
---|
29 | installed -- simple, no setuptools to run, no Eggs to install, no |
---|
30 | non-standard library dependencies. |
---|
31 | |
---|
32 | You can find `asciidocapi.py` in the AsciiDoc |
---|
33 | http://www.methods.co.nz/asciidoc/INSTALL.html#X1[distribution |
---|
34 | archives] (version 8.4.1 or better). |
---|
35 | |
---|
36 | Once you have `asciidocapi.py` Verify everything is working by running |
---|
37 | the module doctests: |
---|
38 | |
---|
39 | python asciidocapi.py |
---|
40 | |
---|
41 | If there are no messages then all is well. |
---|
42 | |
---|
43 | The following minimal example compiles `mydoc.txt` to `mydoc.html`: |
---|
44 | |
---|
45 | [source,python] |
---|
46 | ------------------------------------------------------------------------------- |
---|
47 | from asciidocapi import AsciiDocAPI |
---|
48 | asciidoc = AsciiDocAPI() |
---|
49 | asciidoc.execute('mydoc.txt') |
---|
50 | ------------------------------------------------------------------------------- |
---|
51 | |
---|
52 | The next interactive example uses file-like objects for input and output: |
---|
53 | |
---|
54 | ------------------------------------------------------------------------------- |
---|
55 | $ python |
---|
56 | Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52) |
---|
57 | [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 |
---|
58 | Type "help", "copyright", "credits" or "license" for more information. |
---|
59 | >>> from asciidocapi import AsciiDocAPI |
---|
60 | >>> import StringIO |
---|
61 | >>> infile = StringIO.StringIO('Hello *{author}*') |
---|
62 | >>> outfile = StringIO.StringIO() |
---|
63 | >>> asciidoc = AsciiDocAPI() |
---|
64 | >>> asciidoc.options('--no-header-footer') |
---|
65 | >>> asciidoc.attributes['author'] = 'Joe Bloggs' |
---|
66 | >>> asciidoc.execute(infile, outfile, backend='html4') |
---|
67 | >>> print outfile.getvalue() |
---|
68 | <p>Hello <strong>Joe Bloggs</strong></p> |
---|
69 | |
---|
70 | >>> |
---|
71 | ------------------------------------------------------------------------------- |
---|
72 | |
---|
73 | |
---|
74 | Implementation Rationale |
---|
75 | ------------------------ |
---|
76 | .Leverage existing knowledge |
---|
77 | The API maps directly onto the `asciidoc(1)` command -- this is |
---|
78 | deliberate -- if you know the `asciidoc(1)` command learning the API |
---|
79 | will be trivial. A nice side effect of this goal is that API and |
---|
80 | command-line modes share the same code -- virtually no `asciidoc(1)` |
---|
81 | code is specific to API usage. |
---|
82 | |
---|
83 | .Simplicity |
---|
84 | Implemented with a single Python module file (`asciidocapi.py`) |
---|
85 | containing the 'AsciiDocAPI' API class. 'AsciiDocAPI' contains just |
---|
86 | one method plus a few attributes for processing options and result |
---|
87 | messages. No external setup tools and no non-standard library |
---|
88 | dependencies are used or required. |
---|
89 | |
---|
90 | .Loose coupling |
---|
91 | The dependency between `asciidocapi.py` and `asciidoc.py` is minimal |
---|
92 | -- the current `asciidocapi.py` module uses only two attributes and |
---|
93 | one function from the `asciidoc.py` module. |
---|
94 | |
---|
95 | .Why isn't the API baked right into the asciidoc.py command script? |
---|
96 | 1. You can't just drop `asciidoc.py` into your application because it |
---|
97 | requires all the related config files and filters -- complex and |
---|
98 | unnecessary since all this was already done when you installed |
---|
99 | AsciiDoc. |
---|
100 | 2. This scheme separates the API from the AsciiDoc application -- the |
---|
101 | API implementation can be extended or replaced independently of |
---|
102 | AsciiDoc. |
---|
103 | |
---|
104 | |
---|
105 | API reference |
---|
106 | ------------- |
---|
107 | |
---|
108 | [[X2]] |
---|
109 | Class `AsciiDocAPI(object)` |
---|
110 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
111 | This is the 'AsciiDoc' API class. |
---|
112 | |
---|
113 | Instance attributes |
---|
114 | ^^^^^^^^^^^^^^^^^^^ |
---|
115 | `asciidoc`:: |
---|
116 | The imported `asciidoc.py` module. |
---|
117 | |
---|
118 | `attributes`:: |
---|
119 | A dictionary of AsciiDoc attribute values passed to AsciiDoc. |
---|
120 | |
---|
121 | - Setting an attribute value to `None` (`name: None`) will undefine |
---|
122 | (delete) the attribute (this in addition to the `name!` attribute |
---|
123 | name format that the `asciidoc(1)` command uses). |
---|
124 | - To simply define an attribute set the attribute value to a blank |
---|
125 | string (`name: ''`) |
---|
126 | |
---|
127 | `cmd`:: |
---|
128 | The file path of the `asciidoc.py` script. Set by the `__init__` |
---|
129 | method. |
---|
130 | |
---|
131 | `messages`:: |
---|
132 | A chronologically ordered list of message strings generated during |
---|
133 | AsciiDoc execution (last message at the end of the list). |
---|
134 | |
---|
135 | `options`:: |
---|
136 | An instance of the <<X1,Options class>>. Contains a list of command |
---|
137 | options passed to AsciiDoc. |
---|
138 | |
---|
139 | Instance methods |
---|
140 | ^^^^^^^^^^^^^^^^ |
---|
141 | `__init__(self, asciidoc_py=None)`:: |
---|
142 | Locate and import `asciidoc.py` module and verify API compatibility. |
---|
143 | Initialize instance attributes. A search for the `asciidoc` module is |
---|
144 | made in the following order: |
---|
145 | |
---|
146 | . Use the `ASCIIDOC_PY` environment variable if it is set. |
---|
147 | . Use the `asciidoc_py` argument if it is set. |
---|
148 | . Search the environment 'PATH' for `asciidoc.py`, `asciidoc.pyc` and |
---|
149 | `asciidoc` (in that order). |
---|
150 | . Finally repeat the previous search in the current working directory. |
---|
151 | |
---|
152 | `execute(self, infile, outfile=None, backend=None)`:: |
---|
153 | Compile `infile` to `outfile` using `backend` format. `infile` and |
---|
154 | `outfile` can be file path strings or file-like objects. `backend` is |
---|
155 | name of 'AsciiDoc' backend (takes same values as `asciidoc(1)` command |
---|
156 | `--backend` option). If `outfile` or `backend` are `None` then their |
---|
157 | respective `asciidoc(1)` defaults are used. |
---|
158 | |
---|
159 | |
---|
160 | [[X1]] |
---|
161 | Class `Options(object)` |
---|
162 | ~~~~~~~~~~~~~~~~~~~~~~~ |
---|
163 | Stores `asciidoc(1)` command options. You can use any `asciidoc(1)` |
---|
164 | options with the exception of the `--doctest` and `--filter` options. |
---|
165 | |
---|
166 | Instance attributes |
---|
167 | ^^^^^^^^^^^^^^^^^^^ |
---|
168 | `values`:: |
---|
169 | The list of `(name,value)` command option tuples. |
---|
170 | |
---|
171 | Instance methods |
---|
172 | ^^^^^^^^^^^^^^^^ |
---|
173 | `__call__(self, name, value=None)`:: |
---|
174 | A shortcut for the `append` method. Example: |
---|
175 | |
---|
176 | opts = Options() |
---|
177 | opts('--verbose') |
---|
178 | |
---|
179 | `append(self, name, value=None)`:: |
---|
180 | Append `(name,value)` to the options list. Example: |
---|
181 | |
---|
182 | opts = Options() |
---|
183 | opts.append('--conf-file', 'blog.conf') |
---|
184 | |
---|
185 | |
---|
186 | Class `AsciiDocError(Exception)` |
---|
187 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
188 | Thrown by the <<X2,AsciiDocAPI class>> when an 'AsciiDoc' execution |
---|
189 | error occurs. |
---|