2015-10-21 3 views
2

Я создал привязки python для большого тела кода C++, используя boost :: python. Связи python имеют такие документы:Как создать doxygen docs из boost :: python docstrings?

BOOST_PYTHON_MODULE(mymodule) 
{ 
    using namespace boost::python; 
    def("foo1", foo1, arg("i"), "foo1 doc"); 
} 

Остальная часть проекта документирована с использованием doxygen. Я хотел бы знать, есть ли способ создать doxygen docs из docstrings привязок python.

Мне кажется, что у меня есть два варианта:

  • Используйте волшебный инструмент, чтобы импортировать файл питона и вывода документов. Sphinx работает в определенной степени, так как его средство autodoc фактически загружает модули python и сканирует докстроны. Тем не менее, он не создает выходной формат doxygen, который может использовать (я думаю?).
  • Напишите процесс преобразования, чтобы импортировать BOOST_PYTHON_MODULE. Вызовите help (mymodule). Разберите вывод для создания файлов python скелета. Подавайте их в кислород, как обычно.

Есть ли лучший способ?

ответ

2

С this topic, вы можете сделать следующее:

1 - Написать в документации Doxygen:

// DocString: foo 
/** 
* @brief Foo doc 
* @param i an integer 
* @return something 
* 
*/ 
int foo(int i); 

2 - Обновление привязки документ:

BOOST_PYTHON_MODULE(mymodule) 
{ 
    using namespace boost::python; 
    def("foo1", foo1, arg("i"), "@DocString(foo)"); 
} 

3 - Настройка файла (в цепочке сборки) со сценарием следующим образом:

import re 
import sys 

def parse_doc_string(istr): 
    pattern = re.compile(r'@(\w+)\s+(.*)') 
    docstring = list() 
    for line in map(lambda s : s.strip(), istr): 
     if line == '/**': 
      continue 
     if line == '*/': 
      return docstring 
     line = line.lstrip('* ') 
     match = pattern.match(line) 
     if match: 
      docstring.append((match.group(1), match.group(2))) 

def extract(istr, docstrings): 
    pattern = re.compile(r'^//\s*DocString:\s*(\w+)$') 
    for line in map(lambda s : s.strip(), istr): 
     match = pattern.match(line) 
     if match: 
      token = match.group(1) 
      docstrings[token] = parse_doc_string(istr) 

def format_doc_string(docstring): 
    return '\n'.join('{}: {}'.format(k, v) for (k, v) in docstring) 

def escape(string): 
    return string.replace('\n', r'\n') 

def substitute(istr, ostr, docstrings): 
    pattern = re.compile(r'@DocString\((\w+)\)') 
    for line in map(lambda s : s.rstrip(), istr): 
     for match in pattern.finditer(line): 
      token = match.group(1) 
      docstring = format_doc_string(docstrings[token]) 
      line = line.replace(match.group(0), escape(docstring)) 
     print(line, file=ostr) 

if __name__ == '__main__': 
    sourcefile = sys.argv[1] 
    docstrings = dict() 
    with open(sourcefile) as istr: 
     extract(istr, docstrings) 
    with open(sourcefile) as istr: 
     with sys.stdout as ostr: 
      substitute(istr, ostr, docstrings) 

Он заменит ваше переплетение на:

def("foo1", foo1, arg("i"), "brief: Foo doc\nparam: i an integer\nreturn: something");