Permalink
Browse files

DOC: add automatic documentation generation from C sources (using Dox…

…ygen at the moment)
  • Loading branch information...
1 parent 5e4cd57 commit e520cdd88f53448bbd5fb7b9ef06fa22635d5189 @pv pv committed Jun 5, 2010
Showing with 1,719 additions and 0 deletions.
  1. +1,571 −0 doc/cdoc/Doxyfile
  2. +7 −0 doc/cdoc/Makefile
  3. +31 −0 doc/cdoc/README
  4. +110 −0 doc/cdoc/numpyfilter.py
View
Oops, something went wrong.
View
@@ -0,0 +1,7 @@
+all: build
+
+build:
+ doxygen
+
+.PHONY: all build
+
View
@@ -0,0 +1,31 @@
+cdoc
+====
+
+This is a simple Doxygen project for building Numpy C code documentation,
+with docstrings extracted from the C sources themselves.
+
+The understood syntax for documentation in the C source is
+
+ /*
+ * Some text in reStructuredText format
+ */
+ int function_to_which_the_text_applies()
+ {
+ ...
+ }
+
+ /*
+ * More text in reStructuredText format
+ */
+ struct
+ {
+ int variable_1; /* Documentation for variable_1 */
+
+ /*
+ * Documentation for variable_2
+ */
+ int variable_2;
+ } struct_name_t;
+
+Please do not use JavaDoc or Doxygen-specific formatting at the moment.
+
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+"""
+numpyfilter.py INPUTFILE
+
+Interpret C comments as ReStructuredText, and replace them by the HTML output.
+Also, add Doxygen /** and /**< syntax automatically where appropriate.
+
+"""
+import sys
+import re
+import os
+import textwrap
+import optparse
+import cPickle as pickle
+
+CACHE_FILE = 'build/rst-cache.pck'
+
+def main():
+ p = optparse.OptionParser(usage=__doc__.strip())
+ options, args = p.parse_args()
+
+ if len(args) != 1:
+ p.error("no input file given")
+
+ comment_re = re.compile(r'(\n.*?)/\*(.*?)\*/', re.S)
+
+ cache = load_cache()
+
+ f = open(args[0], 'r')
+ try:
+ text = f.read()
+ text = comment_re.sub(lambda m: process_match(m, cache), text)
+ sys.stdout.write(text)
+ finally:
+ f.close()
+ save_cache(cache)
+
+def filter_comment(text):
+ if text.startswith('NUMPY_API'):
+ text = text[9:].strip()
+ if text.startswith('UFUNC_API'):
+ text = text[9:].strip()
+
+ html = render_html(text)
+ return html
+
+def process_match(m, cache=None):
+ pre, rawtext = m.groups()
+
+ preline = pre.split("\n")[-1]
+
+ if cache is not None and rawtext in cache:
+ text = cache[rawtext]
+ else:
+ text = re.compile(r'^\s*\*', re.M).sub('', rawtext)
+ text = textwrap.dedent(text)
+ text = filter_comment(text)
+
+ if cache is not None:
+ cache[rawtext] = text
+
+ if preline.strip():
+ return pre + "/**< " + text + " */"
+ else:
+ return pre + "/** " + text + " */"
+
+def load_cache():
+ if os.path.exists(CACHE_FILE):
+ f = open(CACHE_FILE, 'rb')
+ try:
+ cache = pickle.load(f)
+ except:
+ cache = {}
+ finally:
+ f.close()
+ else:
+ cache = {}
+ return cache
+
+def save_cache(cache):
+ f = open(CACHE_FILE + '.new', 'wb')
+ try:
+ pickle.dump(cache, f)
+ finally:
+ f.close()
+ os.rename(CACHE_FILE + '.new', CACHE_FILE)
+
+def render_html(text):
+ import docutils.parsers.rst
+ import docutils.writers.html4css1
+ import docutils.core
+
+ docutils.parsers.rst.roles.DEFAULT_INTERPRETED_ROLE = 'title-reference'
+ writer = docutils.writers.html4css1.Writer()
+ parts = docutils.core.publish_parts(
+ text,
+ writer=writer,
+ settings_overrides = dict(halt_level=5,
+ traceback=True,
+ default_reference_context='title-reference',
+ stylesheet_path='',
+ # security settings:
+ raw_enabled=0,
+ file_insertion_enabled=0,
+ _disable_config=1,
+ )
+ )
+ return parts['html_body'].encode('utf-8')
+
+if __name__ == "__main__": main()

0 comments on commit e520cdd

Please sign in to comment.