1 """Additional Python code for ELinks maintainers.
3 This module is intended for ELinks maintainers. If you modify or add to
4 the Python APIs in src/scripting/python/*.c and/or contrib/python/hooks.py,
5 you should update the accompanying docstrings to reflect your changes and
6 then generate a new version of the file doc/python.txt (which serves as a
7 reference manual for the browser's Python APIs). The embedded interpreter
8 can use introspection to regenerate the python.txt document for you; just
9 copy this file into your ~/.elinks directory and add something like the
10 following to ~/.elinks/hooks.py:
13 elinks.bind_key('F2', elinks_maint.generate_python_txt)
22 Python programmers can customize the behavior of ELinks by creating a Python
23 hooks module. The embedded Python interpreter provides an internal module
24 called elinks that can be used by the hooks module to create keystroke
25 bindings for Python code, obtain information about the document being
26 viewed, display simple dialog boxes and menus, load documents into the
27 ELinks cache, or display documents to the user. These two modules are
43 separator
= '-' * 78 + '\n'
45 def document_modules(*modules
):
46 """Format the internal documentation found in one or more Python modules."""
48 for module
in modules
:
49 name
, doc
, namespace
= module
.__name
__, module
.__doc
__, module
.__dict
__
50 if not name
or not namespace
:
53 summary
, junk
, description
= doc
.rstrip().split('\n', 2)
55 summary
, description
= '?', '(no description available)'
56 functions
= document_functions(namespace
)
57 output
.append(module_template
% (name
, summary
, indent(description
),
59 return separator
.join(output
)
61 def document_functions(namespace
):
62 """Format the internal documentation for all functions in a namespace."""
63 objects
= namespace
.items()
66 for name
, object in objects
:
67 if name
.startswith('_'):
69 species
= type(object)
70 if species
== types
.BuiltinFunctionType
:
72 elif species
== types
.FunctionType
:
73 args
= inspect
.formatargspec(*inspect
.getargspec(object))
76 description
= inspect
.getdoc(object)
77 output
.append('%s%s\n%s\n' % (name
, args
, indent(description
)))
78 return '\n'.join(output
)
80 def generate_python_txt():
81 """Generate documentation for the hooks and elinks modules."""
85 # Remove anything that doesn't belong in the API documentation.
87 hooks_api_functions
= (
90 'pre_format_html_hook',
94 for key
in hooks
.__dict
__.keys():
95 if key
not in hooks_api_functions
and not key
.startswith('_'):
96 del hooks
.__dict
__[key
]
97 hooks
.__doc
__ = hooks
.__doc
__.replace('Example Python', 'Python')
99 # Generate the documentation.
102 output
= separator
.join((preface
, document_modules(hooks
, elinks
)))
104 # Restore the hooks module to a sane state.
107 # View the documentation.
109 path
= write_tempfile(output
)
113 """Return indented text."""
115 return '\n'.join([indent
+ line
for line
in text
.split('\n')])
117 def write_tempfile(text
):
118 """Write a string to a temporary file and return the file's name."""
119 output
= tempfile
.NamedTemporaryFile(prefix
='elinks_maint', suffix
='.txt')
122 _tempfiles
[text
] = output
125 # Temp files are stashed in this dictionary to prevent them from being closed
126 # before ELinks has a chance to read them; they will be automatically deleted
127 # when the dictionary is garbage-collected at exit time.